using DotNetCore.CAP;
using Exceptionless;
using HlxEbc.BAL.BAS;
using HlxEbc.Common;
using HlxEbc.Common.Helper;
using HlxEbc.Data;
using HlxEbc.Data.MS;
using HlxEbc.Data.MS.Delivery;
using HlxEbc.Data.MS.Produce;
using HlxEbc.Data.Ten.Print;
using HlxEbc.Data.ViewModel;
using HlxEbc.Data.ViewModel.BAS.CompanyCapitalflow;
//using hlxERP.Data.ViewModel.ReportDataSource;
using HlxEbc.Data.ViewModel.Enums;
using HlxEbc.Data.ViewModel.MS;
using HlxEbc.Data.ViewModel.Report;
using HlxEbc.Data.ViewModel.SALE;
using HlxEbc.Data.ViewModel.Stock;
using HlxEbc.Data.ViewModel.SYS.Tenant;
using HlxEbc.Data.ViewModel.SYS.User;
using HlxEbc.IBAL;
using HlxEbc.IBAL.MS;
using HlxEbc.InsideService;
using HlxEbc.InsideService.Finance;
using Refit;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HlxEbc.BAL.MS
{
    public class StrogeBal : BaseBal, IStrogeBal/*, IReportDataSourceBal*/
    {
        protected static readonly string _billNameCode = "MS_Stroge";
        protected static string _billRoleType = BillRoleTypeEnum.InStock.ToString();
        protected static readonly string _FieldName = "BillNo";


        private readonly ICapPublisher _capBus;
        public StrogeBal(ICapPublisher capPublisher)
       : base()
        {
            _capBus = capPublisher;
        }
        /// <summary>
        /// 新增单据
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public BalResult Add(UserToken userToken, MSStrogeCreateModel model)
        {
            var result = new BalResult();
            if (model == null)
            {
                result.IsSuccess = false;
                result.Msg = "参数不可为空";
            }

            var matIds = new List<Guid>();
            var barCodes = new List<MS_BarCode>();
            var barCodeTracks = new List<MS_BarCodeTrack>();
            if (model.BarCodes.Count > 0)
            {
                barCodes = _client.Queryable<MS_BarCode>().Where(t => t.TenantId == userToken.TenantId && model.BarCodes.Contains(t.BarCode)).ToList();
                if (model.StrogeDetails == null || model.StrogeDetails.Count == 0)
                    model.StrogeDetails = barCodes.GroupBy(t => new { t.MaterialId, t.ColorName, t.SizeName, t.Specs, })
                        .Select(t => new MSStrogeDetailCreateModel { MaterialId = t.Key.MaterialId, ColorName = t.Key.ColorName, SizeName = t.Key.SizeName, Specs = t.Key.Specs, Qty = t.Sum(a => a.Qty), }).Distinct().ToList();

                matIds = barCodes.Select(t => t.MaterialId).Distinct().ToList();
            }
            else
            {
                matIds = model.StrogeDetails.Select(t => t.MaterialId).Distinct().ToList();
                if (model.StrogeDetails.Where(t => t.Qty < 0).Any())
                {
                    var data = model.StrogeDetails.GroupBy(t => new { t.MaterialId, t.MaterialNo, t.ColorName, t.SizeName })
                        .Select(t => new { t.Key.MaterialId, t.Key.MaterialNo, t.Key.ColorName, t.Key.SizeName, Qty = t.Sum(a => a.Qty), }).ToList();
                    if (data.Where(t => t.Qty < 0).Any())
                    {
                        foreach (var item in data)
                        {
                            if (item.Qty > 0)
                                continue;
                            result.Msg = $"{item.MaterialNo}{item.ColorName}{item.SizeName}订单数不可为{item.Qty}";
                            return result;
                        }
                    }
                }
            }
            var mats = _client.Queryable<BAS_Material>().Where(t => t.TenantId == userToken.TenantId && matIds.Contains(t.MaterialId)).ToList();
            var entity = ObjectHelper.Mapper<MS_Stroge, MSStrogeCreateModel>(model);
            if (entity.Id == Guid.Empty)
                entity.Id = Guid.NewGuid();
            entity.CreateTime = DateTime.Now;
            entity.Creator = userToken.UserId;
            entity.TenantId = userToken.TenantId;

            if (string.IsNullOrWhiteSpace(entity.BillNo))
            {
                var _billCodeRulesBal = RefitExtensions.For<IBillCodeRulesAPI>(Appsettings.BaseUrl);
                var billNo = _billCodeRulesBal.BuilderNewNo(model.BillType * 10 + model.ClassId, _billNameCode, _FieldName, entity.CompanyId, entity.DepotId, userToken.Token);
                entity.BillNo = billNo.Result;
                //entity.CompanyBillNo = _billCodeRulesBal.BuilderNewNo(model.BillType * 10 + model.ClassId, _billNameCode, "CompanyBillNo", entity.CompanyId, entity.DepotId, userToken.Token).Result;
            }
            var details = new List<MS_StrogeDetail>();
            StockOutInModel stockDetails = new StockOutInModel() { BillDate = entity.BillDate, DeptId = model.DepotId, Commond = model.Commond, CompanyId = entity.CompanyId, RelatedBillNo = entity.RelatedBillNo, Remark = entity.Remark, BillType = entity.BillType };
            stockDetails.Details = new List<ProStockDetailOutInModel>();
            foreach (var item in model.StrogeDetails)
            {
                if (item.Id == Guid.Empty)
                    item.Id = Guid.NewGuid();

                var mat = mats.Where(t => t.MaterialId == item.MaterialId).FirstOrDefault();
                //var detail = ObjectHelper.Mapper<MS_StrogeDetail, MSStrogeDetailCreateModel>(item);
                var detail = new MS_StrogeDetail()
                {
                    DescQty = 0,
                    SizeName = item.SizeName,
                    SourceBillNo = item.SourceBillNo,
                    Specs = item.Specs,
                    StrogeId = entity.Id,
                    ColorName = item.ColorName,
                    CreateTime = DateTime.Now,
                    Creator = userToken.UserId,
                    DespachoQty = 0,
                    EntradaQty = 0,
                    Id = item.Id,
                    MaterialId = item.MaterialId,
                    MaterialName = mat.MaterialName,
                    MaterialNo = mat.MaterialNo,
                    OrderId = item.OrderId,
                    PhotoUrl = mat.PhotoUrl,
                    Price = item.Price,
                    Qty = item.Qty,
                    Remark = item.Remark,
                    TenantId = userToken.TenantId,
                    Total = item.Total,
                    UnitName = item.UnitName,
                    UseProductNo = item.UseProductNo,
                    VatNo = item.VatNo,
                    PositionNo = item.PositionNo,
                    Weight = item.Weight,
                    Tax = item.Tax,
                    Taxprice = item.Taxprice,
                };
                if (entity.BillType == 41)
                    if (entity.DepotStatus == 2)
                    {
                        detail.DescQty = 0;
                        detail.EntradaQty = detail.Qty;
                    }
                    else
                    {
                        detail.DescQty = detail.Qty;
                        detail.EntradaQty = 0;
                    }
                else if (entity.BillType == 40)
                {
                    if (entity.DepotStatus == 5)
                    {
                        detail.DescQty = 0;
                        detail.DespachoQty = detail.Qty;
                    }
                    else
                    {
                        detail.DescQty = detail.Qty;
                        detail.DespachoQty = 0;
                    }
                }
                details.Add(detail);

                var stockTemp = new ProStockDetailOutInModel()
                {
                    SizeName = item.SizeName,
                    IsSample = false,
                    ColorName = item.ColorName,
                    Specs = item.Specs,
                    VatNo = item.VatNo,
                    TransactionPrice = item.Price,
                    TotalQty = item.Qty,
                    Remark = item.Remark,
                    UnitId = item.UnitName,
                    UnitName = item.UnitName,
                    MaterialId = item.MaterialId
                };
                stockDetails.Details.Add(stockTemp);

                var barCodeTemps = barCodes?.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Specs == item.Specs).ToList();

                foreach (var temp in barCodeTemps)
                {
                    temp.BillDetailId = detail.Id;
                    temp.BillId = entity.Id;
                    if (model.BillType == 40)
                        temp.CompanyId = entity.CompanyId;
                    else
                        temp.CompanyId = entity.DepotId;
                    temp.BillType = "MS_Stroge";
                    temp.Status = (int)BarCodeStatusEnum.MS_Stroge;
                    if (entity.BillType == 41)
                    {
                        temp.PositionNo = detail.PositionNo;
                        temp.Status = (int)BarCodeStatusEnum.MS_Stock;
                    }
                    else
                    {
                        temp.PositionNo = "";
                    }
                    barCodeTracks.Add(new MS_BarCodeTrack() { BarCode = temp.BarCode, CommonType = 0, BillDetailId = detail.Id, BillId = detail.StrogeId, Status = 2, BillNo = entity.BillNo, BillType = "MS_Stroge", BundleCode = "", CompanyId = entity.CompanyId, CreateTime = DateTime.Now, Creator = userToken.UserId, Id = Guid.NewGuid(), TenantId = userToken.TenantId, TeamNo = model.DcNo, Qty = temp.Qty, Operation = entity.BillType, EntradaQty = entity.BillType == 41 ? temp.Qty : 0, DespachoQty = entity.BillType == 40 ? temp.Qty : 0, MachineNo = entity.DcNo, MemberId = userToken.MemberId, PositionNo = temp.PositionNo, ProcessId = temp.ProcessId, });
                }
            }

            entity.TotalQty = details.Sum(t => t.Qty);
            entity.DescQty = details.Sum(t => t.DescQty);
            entity.EntradaQty = details.Sum(t => t.EntradaQty);
            entity.DespachoQty = details.Sum(t => t.DespachoQty);
            entity.Total = details.Sum(t => t.Total);

            var flowSet = RefitExtensions.For<ITenantSysSetAPI>(Appsettings.BaseUrl).GetTenantSet(new Data.ViewModel.SYS.Set.SysSetSearchModel() { SetTypeKey = "BillFlow", ItemKey = "FlowSet", DetailKey = "OutBoundDetailFlow" }, userToken.Token).Result;
            if (flowSet != null)
            {
                if (flowSet?.SetTenantValue?.SetItemValue.ToLower() != "true")
                {
                    entity.Status = 1;
                }
            }

            var dept = _client.Queryable<HR_Dept>().Where(t => t.DeptID == entity.DepotId).First();
            var _stocksBal = new StocksBal(_capBus);
            if (entity.BillType == 41 && entity.DepotStatus == 2)
            {
                entity.Status = 3;
                if (dept.IsVerifyStock)
                {
                    var stockData = _stocksBal.GetStockQty(userToken, details.Select(t => t.MaterialId).Distinct().ToList()).Result;
                    if (stockData.Count == 0 && details.Where(t => t.Qty < 0).Any())
                    {
                        result.IsSuccess = false;
                        result.Msg = "产品无库存";
                        return result;
                    }
                    var nv = from s in details
                             join d in stockData.Where(t => t.DeptId == entity.DepotId).ToList() on new { s.MaterialId, s.ColorName, s.SizeName, SpecsName = s.Specs, s.VatNo } equals new { d.MaterialId, d.ColorName, d.SizeName, d.SpecsName, d.VatNo } into sdv
                             from sd in sdv.DefaultIfEmpty()
                             select new { s.MaterialId, s.MaterialNo, s.ColorName, s.SizeName, s.Specs, s.VatNo, DescQty = s.Qty, Qty = sd != null ? sd.Qty : 0 }
                            ;
                    var nvList = nv.Where(t => t.DescQty < 0 && Math.Abs(t.DescQty) > t.Qty).ToList();
                    if (nvList.Count() > 0)
                    {
                        var msg = "";
                        foreach (var item in nvList)
                        {
                            msg += $"{item.MaterialNo}{(!string.IsNullOrEmpty(item.ColorName) ? "-" : "")}{item.ColorName}{(!string.IsNullOrEmpty(item.SizeName) ? "-" : "")}{item.SizeName}{(!string.IsNullOrEmpty(item.Specs) ? "-" : "")}{item.Specs}{(!string.IsNullOrEmpty(item.VatNo) ? "-" : "")}{item.VatNo};";
                        }
                        result.IsSuccess = false;
                        result.Msg = msg + "仓库库存不足";
                        return result;
                    }
                }
            }
            else if (entity.BillType == 40 && entity.DepotStatus == 5)
            {
                entity.Status = 3;
                if (dept.IsVerifyStock)
                {
                    var stockData = _stocksBal.GetStockQty(userToken, matIds).Result;
                    foreach (var item in details)
                    {
                        var msg = $"款号:{item.MaterialNo}{(!string.IsNullOrEmpty(item.ColorName) ? ",颜色:" : "")}{item.ColorName}{(!string.IsNullOrEmpty(item.SizeName) ? ",尺码:" : "")}{item.SizeName}{(!string.IsNullOrEmpty(item.Specs) ? ",规格:" : "")}{item.Specs}{(!string.IsNullOrEmpty(item.VatNo) ? ",缸号:" : "")}{item.VatNo}";

                        var any = stockData.Where(t => t.DeptId == entity.DepotId && t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.SpecsName == item.Specs && t.VatNo == item.VatNo);
                        if (any.Any())
                        {
                            var temp = any.First();
                            if (temp.Qty < item.Qty)
                            {
                                result.IsSuccess = false;
                                result.Msg = $"{msg },仓库:{dept.DeptName}库存{temp.Qty}需求{item.Qty}，扣除不足";
                                return result;
                            }
                        }
                        else
                        {
                            OperateLog(new OperateLogModel() { TenantId = userToken.TenantId, OldValue = JsonSerializerHelper.Encode(stockData), NewValue = JsonSerializerHelper.Encode(details), CommandType = 0, DiffType = "TempLog", Parameters = JsonSerializerHelper.Encode(model), });
                            result.IsSuccess = false;
                            result.Msg = $"{msg},仓库:{dept.DeptName}无库存";
                            return result;
                        }
                    }
                }
            }
            try
            {
                var r = _client.Insertable(entity).ExecuteCommand();
                result.IsSuccess = r > 0;
                if (result.IsSuccess)
                {
                    _client.Insertable(details).ExecuteCommand();

                    stockDetails.BarCodes = model.BarCodes;

                    if (result.IsSuccess)
                    {
                        if (model.BarCodes.Count > 0)
                        {
                            _client.Updateable(barCodes).ExecuteCommand();
                        }
                        if (barCodeTracks.Count > 0)
                        {
                            _client.Insertable(barCodeTracks).ExecuteCommand();
                            var barcodes = barCodes.Select(t => t.BarCode).ToList();
                            _client.Deleteable<MS_BarCodeScanTemp>().Where(t => t.TenantId == userToken.TenantId && barcodes.Contains(t.BarCode)).ExecuteCommand();
                        }
                        result.Msg = entity.Id.ToString();

                        new Task(() =>
                        {
                            var matNameList = details.Select(t => $"{t.MaterialName}{t.ColorName}{t.SizeName}{t.Specs}{t.VatNo}:{t.Qty}{t.UnitName}").ToList();
                            OperateLog(new OperateLogModel
                            {
                                TenantId = userToken.TenantId,
                                BillId = entity.Id,
                                Creator = userToken.UserId,
                                CreatorName = userToken.UserName,
                                BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                                BillNo = entity.BillNo,
                                RelationType = "",
                                RelationBillNo = "",
                                CreateTime = DateTime.Now,
                                CommandName = $"新建{(entity.BillType == 40 ? "出库" : "入库")}单",
                                TableName = entity.GetType().Name,
                                Remark = $"新建{(entity.BillType == 40 ? "出库" : "入库")}单",
                                NewValue = JsonSerializerHelper.Encode(new { entity = entity, Details = details }),
                            });
                        }).Start();

                        var msgapi = RefitExtensions.For<IWeChatPrivateTemplateAPI>(Appsettings.BaseUrl);
                        var newentity = GetById(userToken, entity.Id);
                        msgapi.StrogeWeChatMessageCustomizeData(new MsgMSStrogeModel()
                        {
                            Entity = newentity,
                            OperatType = 0
                        }, userToken.Token);
                    }
                    else
                    {
                        _client.Deleteable(entity).ExecuteCommand();
                        _client.Deleteable(details).ExecuteCommand();
                    }
                }
                var sr = _stocksBal.ModifyStockQty(userToken, matIds).Result;
            }
            catch
            {
                throw;
            }

            return result;
        }

        /// <summary>
        /// 编辑单据
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public BalResult Modify(UserToken userToken, MSStrogeModifyModel model)
        {
            var result = new BalResult();
            try
            {
                var orgEntity = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == model.Id).First();

                var OldValue = JsonSerializerHelper.Encode(new { entity = orgEntity, /*Details = orgDetails,*/ });
                //ObjectHelper.CopyModel(model, orgEntity);
                orgEntity.BillDate = model.BillDate;
                orgEntity.Remark = model.Remark;


                _client.Updateable(orgEntity).ExecuteCommand();

                result.IsSuccess = true;
                result.Msg = "操作成功";

                new Task(() =>
                {
                    OperateLog(new OperateLogModel
                    {
                        TenantId = userToken.TenantId,
                        BillId = orgEntity.Id,
                        Creator = userToken.UserId,
                        CreatorName = userToken.UserName,
                        BillType = orgEntity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                        BillNo = orgEntity.BillNo,
                        RelationType = "",
                        RelationBillNo = "",
                        CreateTime = DateTime.Now,
                        CommandName = $"编辑{(orgEntity.BillType == 40 ? "出库" : "入库")}单",
                        TableName = orgEntity.GetType().Name,
                        Remark = $"编辑{(orgEntity.BillType == 40 ? "出库" : "入库")}单",
                        OldValue = OldValue,
                        NewValue = JsonSerializerHelper.Encode(new { entity = orgEntity, /*Details = orgDetails,*/ }),
                    });
                }).Start();
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Msg = ex.Message;
                ex.ToExceptionless().Submit();
            }

            return result;
        }
        public BalResult AddDetail(UserToken userToken, MSStrogeDetailCreateModel model)
        {
            var result = new BalResult();
            var entity = _client.Queryable<MS_Stroge>().Where(a => a.Id == model.StrogeId).First();
            if (entity.IsAutoBuild)
            {
                result.Msg = "非手动创建单据不支持新增明细";
                return result;
            }
            var mat = _client.Queryable<BAS_Material>().Where(a => a.TenantId == userToken.TenantId && a.MaterialId == model.MaterialId).First();
            var detail = new MS_StrogeDetail()
            {
                DescQty = model.Qty,
                SizeName = model.SizeName,
                Specs = model.Specs,
                StrogeId = model.StrogeId,
                ColorName = model.ColorName,
                CreateTime = DateTime.Now,
                Creator = userToken.UserId,
                DespachoQty = 0,
                EntradaQty = 0,
                Id = Guid.NewGuid(),
                MaterialId = model.MaterialId,
                MaterialName = mat.MaterialName,
                MaterialNo = mat.MaterialNo,
                OrderId = model.OrderId,
                PhotoUrl = mat.PhotoUrl,
                Price = model.Price,
                Qty = model.Qty,
                Remark = model.Remark,
                TenantId = userToken.TenantId,
                Total = model.Total,
                UnitName = model.UnitName,
                VatNo = model.VatNo,
                UseProductNo = model.UseProductNo,
                PositionNo = model.PositionNo,
                SourceBillNo = model.SourceBillNo,
                Weight = model.Weight,
            };

            entity.DescQty += model.Qty;
            entity.TotalQty += model.Qty;

            if (entity.BillType == 40)
            {
                if (entity.DescQty == 0)
                    entity.DepotStatus = 5;
                else if (entity.DescQty > 0 && entity.TotalQty != entity.DescQty)
                    entity.DepotStatus = 4;
                else
                    entity.DepotStatus = 3;
            }
            else if (entity.BillType == 41)
            {
                if (entity.DescQty == 0)
                    entity.DepotStatus = 2;
                else if (entity.DescQty > 0 && entity.TotalQty != entity.DescQty)
                    entity.DepotStatus = 1;
                else
                    entity.DepotStatus = 0;
            }
            try
            {
                _client.Updateable(entity).ExecuteCommand();
                _client.Insertable(detail).ExecuteCommand();
                result.IsSuccess = true;

                new Task(() =>
                {
                    var matNameList = $"{detail.MaterialName}{detail.ColorName}{detail.SizeName}{detail.Specs}{detail.VatNo}:{detail.Qty}{detail.UnitName}";
                    OperateLog(new OperateLogModel
                    {
                        TenantId = userToken.TenantId,
                        BillId = entity.Id,
                        Creator = userToken.UserId,
                        CreatorName = userToken.UserName,
                        BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                        BillNo = entity.BillNo,
                        RelationType = "",
                        RelationBillNo = "",
                        CreateTime = DateTime.Now,
                        CommandName = $"修改{(entity.BillType == 40 ? "出库" : "入库")}单",
                        TableName = entity.GetType().Name,
                        Remark = $"新增{(entity.BillType == 40 ? "出库" : "入库")}单明细",
                        NewValue = JsonSerializerHelper.Encode(detail),
                    });
                }).Start();
            }
            catch (Exception)
            {
                throw;
            }
            return result;
        }
        public async Task<BalResult> AddDetail(UserToken userToken, List<MSStrogeDetailCreateModel> model)
        {
            var result = new BalResult();
            var entity = _client.Queryable<MS_Stroge>().Where(a => a.Id == model.First().StrogeId).First();
            if (entity.Status == -1)
            {
                result.Msg = "单据已作废，不可编辑";
                return result;
            }
            var barcodeAny = _client.Queryable<MS_BarCodeTrack>().Where(t => t.BillId == entity.Id).Any();
            if (barcodeAny)
            {
                result.IsSuccess = false;
                result.Msg = $"扫码{(entity.BillType == 40 ? "出" : "入")}库单据不支持修改";
                return result;
            }
            if (model.Where(t => t.Qty < 0).Any())
            {
                var orgDetails = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.StrogeId == entity.Id)
                    .GroupBy(t => new { t.MaterialId, t.ColorName, t.SizeName, })
                    .Select(t => new { t.MaterialId, t.ColorName, t.SizeName, Qty = SqlFunc.AggregateSum(SqlFunc.IIF(t.Qty < 0, t.Qty, SqlFunc.IIF(entity.BillType == 40, t.DespachoQty, t.EntradaQty))), })
                    .ToList();

                foreach (var item in model)
                {
                    if (item.Qty > 0)
                        continue;
                    if (orgDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).Any())
                    {
                        var descQty = orgDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).First();
                        if (item.Qty + descQty.Qty < 0)
                        {
                            result.Msg = $"{item.MaterialNo}{item.ColorName}{item.SizeName}原单据合计数为{descQty.Qty}，新增数不可为{item.Qty}";
                            return result;
                        }
                    }
                    else
                    {
                        result.Msg = $"{item.MaterialNo}{item.ColorName}{item.SizeName}原单据数为0，新增数不可为{item.Qty}";
                        return result;
                    }
                }
            }
            var IsStrogeToSaleOrder = false;
            if (entity.BillType == 40 && entity.SourceBillType / 10 == 2)
            {
                var flowSet = RefitExtensions.For<ITenantSysSetAPI>(Appsettings.BaseUrl).GetTenantSet(new Data.ViewModel.SYS.Set.SysSetSearchModel() { SetTypeKey = "BillFlow", ItemKey = "FlowSet", DetailKey = "IsStrogeToSaleOrder" }, userToken.Token).Result;
                if (flowSet != null)
                {
                    if (flowSet?.SetTenantValue?.SetItemValue.ToLower() == "true")
                    {
                        IsStrogeToSaleOrder = true;
                    }
                }
            }
            var details = new List<MS_StrogeDetail>();
            var addDetails = new List<MS_StrogeDetail>();
            var billSourceRelateds = new List<MS_BillSourceRelated>();
            var updbillSourceRelateds = new List<MS_BillSourceRelated>();
            var matNameList = new StringBuilder();
            foreach (var item in model)
            {
                var detail = new MS_StrogeDetail()
                {
                    DescQty = item.Qty,
                    SizeName = item.SizeName,
                    Specs = item.Specs,
                    StrogeId = item.StrogeId,
                    ColorName = item.ColorName,
                    CreateTime = DateTime.Now,
                    Creator = userToken.UserId,
                    DespachoQty = 0,
                    EntradaQty = 0,
                    Id = Guid.NewGuid(),
                    MaterialId = item.MaterialId,
                    MaterialName = item.MaterialName,
                    MaterialNo = item.MaterialNo,
                    OrderId = item.OrderId,
                    PhotoUrl = item.PhotoUrl,
                    Price = item.Price,
                    Qty = item.Qty,
                    Remark = item.Remark,
                    TenantId = userToken.TenantId,
                    Total = item.Total,
                    UnitName = item.UnitName,
                    VatNo = item.VatNo,
                    UseProductNo = item.UseProductNo,
                    PositionNo = item.PositionNo,
                    SourceBillNo = item.SourceBillNo,
                    Weight = item.Weight,
                    Tax = item.Tax,
                    Taxprice = item.Taxprice,
                };

                if (entity.BillType == 40 && entity.Status == 3)
                {
                    detail.DespachoQty = detail.Qty;
                }
                else if (entity.BillType == 41 && entity.Status == 3)
                {
                    detail.EntradaQty = detail.Qty;
                }
                entity.DescQty += item.Qty;
                entity.TotalQty += item.Qty;
                details.Add(detail);
                matNameList.Append($"{detail.MaterialName}{detail.ColorName}{detail.SizeName}{detail.Specs}{detail.VatNo}:{detail.Qty}{detail.UnitName}");
            }
            //if (entity.BillType == 40)
            //{
            //    entity.DepotStatus = 5;
            //}
            //else if (entity.BillType == 41)
            //{
            //    entity.DepotStatus = 2;
            //}
            var matIds = details.Select(t => t.MaterialId).ToList();
            var colos = details.Select(t => t.ColorName).ToList();
            var sizes = details.Select(t => t.SizeName).ToList();
            var _stocksBal = new StocksBal(_capBus);
            var sbt = entity.SourceBillType / 10;
            var sourceBillNos = new List<string>();
            if (!string.IsNullOrEmpty(entity.SourceBillNo))
            {
                sourceBillNos = entity.SourceBillNo.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
            }

            if (entity.DepotStatus == 5 || entity.DepotStatus == 2)
                switch (sbt)
                {
                    case 1:
                        result.IsSuccess = false;
                        result.Msg = $"采购相关单据不支持新增明细";
                        return result;
                        break;
                    case 2:
                        //var addDetail = details.Where(t => t.Qty > 0).ToList();
                        var addMatIds = details.Select(t => t.MaterialId).ToList();
                        var addColos = details.Select(t => t.ColorName).ToList();
                        var addSizes = details.Select(t => t.SizeName).ToList();

                        //var delDetail = details.Where(t => t.Qty < 0).ToList();
                        //var delMatIds = delDetail.Select(t => t.MaterialId).ToList();
                        //var delColos = delDetail.Select(t => t.ColorName).ToList();
                        //var delSizes = delDetail.Select(t => t.SizeName).ToList();

                        //var addOrderDetails = new List<SALE_OrderDetail>();
                        //var delOrderDetails = new List<SALE_OrderDetail>();
                        //var updOrderDetails = new List<SALE_OrderDetail>();
                        var orderDetails = new List<SALE_OrderDetail>();

                        if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                        {
                            orderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0)
                                .WhereIF(sourceBillNos.Count > 0, (a, b) => sourceBillNos.Contains(b.BillNo))
                                .WhereIF(sourceBillNos.Count == 0, (a, b) => a.Qty - a.DespachoQty > 0)
                                .OrderBy((a, b) => new { b.IsDayEnd, a.CreateTime, })
                                .ToList();
                        }
                        else if (entity.SourceBillType == 25)
                        {
                            //addOrderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            //    .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0 && addMatIds.Contains(a.MaterialId) && addColos.Contains(a.ColorName) && addSizes.Contains(a.SizeName) && a.Qty - a.DespachoQty > 0).ToList();
                            //delOrderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            //    .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0 && delMatIds.Contains(a.MaterialId) && delColos.Contains(a.ColorName) && delSizes.Contains(a.SizeName) && a.DespachoQty > 0).ToList();

                            orderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0)
                                .WhereIF(sourceBillNos.Count > 0, (a, b) => sourceBillNos.Contains(b.BillNo))
                                .WhereIF(sourceBillNos.Count == 0, (a, b) => a.DespachoQty > 0)
                                .OrderBy((a, b) => new { b.IsDayEnd, a.CreateTime, })
                                .ToList();
                        }
                        else
                        {
                            orderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0)
                                .WhereIF(sourceBillNos.Count > 0, (a, b) => sourceBillNos.Contains(b.BillNo))
                                .WhereIF(sourceBillNos.Count == 0, (a, b) => a.DespachoQty > 0)
                                .OrderBy((a, b) => new { b.IsDayEnd, a.CreateTime, })
                                .ToList();
                            //orderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            //    .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0 && delMatIds.Contains(a.MaterialId) && delColos.Contains(a.ColorName) && delSizes.Contains(a.SizeName) && a.DespachoQty > 0).ToList();

                        }
                        var inOrderDetailLists = new List<SALE_OrderDetail>();
                        var inLogs = new List<OperateLogModel>();

                        foreach (var item in details)
                        {
                            if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                            {
                                var orderDetailTotalQty = orderDetails.Sum(t => t.Qty);
                                if (!IsStrogeToSaleOrder && orderDetailTotalQty < item.Qty)
                                {
                                    result.IsSuccess = false;
                                    result.Msg = "订单出库数已超订单数，不允许增加商品";
                                    return result;
                                }
                                orderDetailTotalQty = orderDetails.Sum(t => t.DespachoQty);
                                if (orderDetailTotalQty < Math.Abs(item.Qty) && item.Qty < 0)
                                {
                                    result.IsSuccess = false;
                                    result.Msg = "订单退库数已超订单数";
                                    return result;
                                }
                            }
                            else
                            {
                                var orderDetailTotalQty = orderDetails.Sum(t => t.Qty);
                                if (orderDetailTotalQty < item.Qty)
                                {
                                    result.IsSuccess = false;
                                    result.Msg = "订单退库数已超订单数";
                                    return result;
                                }
                            }
                            if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                            {
                                if (item.Qty > 0)
                                {
                                    var orderDetailTemps = orderDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).ToList();
                                    var itemQty = item.Qty;
                                    var oldprice = item.Price; var newprice = item.Price;
                                    foreach (var orderDetail in orderDetailTemps)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                        Guid tempDetailId = item.Id;
                                        if (item.Price != orderDetail.Price || item.Tax != orderDetail.Tax)
                                        {
                                            if (!addDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Price == orderDetail.Price && t.Tax == orderDetail.Tax).Any())
                                            {//价格不同税率不同且没有分解新增项
                                                item.Price = orderDetail.Price;
                                                item.Tax = orderDetail.Tax;
                                                orderDetail.DespachoQty += (int)tempQty;
                                                orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                            }
                                            else
                                            {
                                                if (addDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Price == orderDetail.Price && t.Tax == orderDetail.Tax).Any())
                                                {
                                                    var temp = addDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Price == orderDetail.Price && t.Tax == orderDetail.Tax).First();
                                                    temp.Qty += tempQty;
                                                    tempDetailId = temp.Id;
                                                }
                                                else
                                                {
                                                    var temp = ObjectHelper.Mapper<MS_StrogeDetail, MS_StrogeDetail>(item);
                                                    temp.Id = Guid.NewGuid();
                                                    tempDetailId = temp.Id;
                                                    temp.Price = orderDetail.Price;
                                                    temp.Tax = orderDetail.Tax;
                                                    temp.Qty = tempQty;
                                                    temp.Taxprice = tempQty * orderDetail.Tax * orderDetail.Price / 100;

                                                    addDetails.Add(temp);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            orderDetail.DespachoQty += (int)tempQty;
                                            orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                        }
                                        itemQty -= tempQty;
                                        var inRelated = new MS_BillSourceRelated()
                                        {
                                            Id = Guid.NewGuid(),
                                            TenantId = userToken.TenantId,
                                            BillId = entity.Id,
                                            BillDetailId = tempDetailId,
                                            SourceBillId = orderDetail.KeyId,
                                            SourceBillDetailId = orderDetail.RecordId,
                                            SourceType = entity.SourceBillType,
                                            Status = 1,
                                            BillType = entity.BillType,
                                            Qty = tempQty,
                                            Wieght = 0,
                                        };
                                        billSourceRelateds.Add(inRelated);
                                        //updOrderDetails.Add(orderDetail);
                                    }
                                    if (itemQty > 0)
                                    {
                                        var keyIds = orderDetails.Select(t => t.KeyId).Distinct().ToList();
                                        var orders = _client.Queryable<SALE_Order>().Where(a => keyIds.Contains(a.KeyId) && a.IsDayEnd == true).ToList();
                                        if (orders.Count == 0)
                                        {
                                            result.IsSuccess = false;
                                            result.Msg = "出货数大于订单数，不允许保存！";
                                            return result;
                                        }
                                        keyIds = orders.Select(t => t.KeyId).Distinct().ToList();
                                        var inOrderDetails = new SALE_OrderDetail();
                                        var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = entity.Id, BillDetailId = item.Id, BillType = entity.BillType, SourceType = entity.SourceBillType, Status = 1, TenantId = entity.TenantId, Qty = itemQty, Wieght = 0, };
                                        if (orderDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).Any())
                                        {
                                            inOrderDetails = orderDetails.Where(t => keyIds.Contains(t.KeyId) && t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).OrderByDescending(t => t.CreateTime).First();

                                            inOrderDetails.Qty += (int)itemQty;
                                            inOrderDetails.CalQty += (int)itemQty;
                                            inOrderDetails.DescQty = 0;
                                            inOrderDetails.DespachoQty += (int)itemQty;

                                            inOrderDetails.Total = inOrderDetails.Price * inOrderDetails.Qty * (1 + inOrderDetails.Tax / 100);
                                            inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;
                                        }
                                        else
                                        {
                                            var sALE_Order = _client.Queryable<SALE_Order, MS_BillSourceRelated>((a, b) => new object[] { JoinType.Left, a.KeyId == b.SourceBillId }).Where((a, b) => b.BillId == entity.Id).OrderBy((a, b) => a.BillDate, OrderByType.Desc).First();
                                            inOrderDetails = new SALE_OrderDetail()
                                            {
                                                RecordId = Guid.NewGuid(),
                                                KeyId = sALE_Order.KeyId,
                                                SizeName = item.SizeName,
                                                ColorName = item.ColorName,
                                                Creator = userToken.UserId,
                                                CreateTime = DateTime.Now,
                                                TenantId = entity.TenantId,
                                                CalQty = Convert.ToInt32(itemQty),
                                                CustSalesMan = "",
                                                CustStyleNo = "",
                                                DealQty = Convert.ToInt32(itemQty),
                                                DescQty = 0,
                                                DespachoQty = Convert.ToInt32(itemQty),
                                                Discount = 100,
                                                EntradaQty = 0,
                                                MaterialId = item.MaterialId,
                                                MaterialName = item.MaterialName,
                                                MaterialNo = item.MaterialNo,
                                                PhotoUrl = item.PhotoUrl,
                                                Price = item.Price,
                                                Qty = Convert.ToInt32(itemQty),
                                                OrgPrice = item.Price,
                                                DealTotal = itemQty * item.Price,
                                                OrgTotal = itemQty * item.Price,
                                                RecordType = 1,
                                                Remark = "",
                                                remPrice = item.Price,
                                                Tax = item.Tax,
                                                Taxprice = item.Tax * item.Price * itemQty / 100,
                                                Total = itemQty * item.Price,
                                                UnitName = item.UnitName,
                                            };
                                            inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;
                                            inOrderDetailLists.Add(inOrderDetails);
                                            inLogs.Add(new OperateLogModel
                                            {
                                                TenantId = userToken.TenantId,
                                                BillId = inOrderDetails.KeyId,
                                                Creator = userToken.UserId,
                                                CreatorName = "",
                                                BillType = Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.销售),
                                                BillNo = entity.BillNo,
                                                RelationType = "",
                                                RelationBillNo = "",
                                                CreateTime = DateTime.Now,
                                                CommandName = $"销售单详情",
                                                TableName = inOrderDetails.GetType().Name,
                                                Remark = "销售单新增销售明细",
                                                NewValue = JsonSerializerHelper.Encode(inOrderDetails),
                                            });
                                        }
                                        inRelated.SourceBillDetailId = inOrderDetails.RecordId;
                                        inRelated.SourceBillId = inOrderDetails.KeyId;
                                        billSourceRelateds.Add(inRelated);
                                    }
                                }
                                else
                                {
                                    var orderDetailTemps = orderDetails.Where(t => t.DespachoQty > 0 && t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).OrderByDescending(t => t.CreateTime).ToList();
                                    var itemQty = Math.Abs(item.Qty);
                                    foreach (var orderDetail in orderDetailTemps)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.DespachoQty ? orderDetail.DespachoQty : itemQty;

                                        orderDetail.DespachoQty -= (int)tempQty;
                                        orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                        itemQty -= tempQty;
                                        var inRelated = new MS_BillSourceRelated()
                                        {
                                            Id = Guid.NewGuid(),
                                            TenantId = userToken.TenantId,
                                            BillId = entity.Id,
                                            BillDetailId = item.Id,
                                            SourceBillId = orderDetail.KeyId,
                                            SourceBillDetailId = orderDetail.RecordId,
                                            SourceType = entity.SourceBillType,
                                            Status = 1,
                                            BillType = entity.BillType,
                                            Qty = -tempQty,
                                            Wieght = 0,
                                        };
                                        billSourceRelateds.Add(inRelated);

                                        //updOrderDetails.Add(orderDetail);
                                    }
                                    if (itemQty > 0)
                                    {
                                        result.IsSuccess = false;
                                        result.Msg = "订单退库数已超订单出数";
                                        return result;
                                    }
                                }
                            }
                            else
                            {
                                var orderDetailTemps = orderDetails.Where(t => t.Qty - t.EntradaQty > 0).OrderByDescending(t => t.CreateTime).ToList();
                                var itemQty = item.Qty;
                                foreach (var orderDetail in orderDetailTemps)
                                {
                                    if (itemQty == 0)
                                        break;
                                    var tempQty = itemQty > orderDetail.Qty - orderDetail.EntradaQty ? orderDetail.Qty - orderDetail.EntradaQty : itemQty;
                                    item.EntradaQty += (int)tempQty;
                                    item.DespachoQty -= (int)tempQty;
                                    item.DescQty = item.Qty - item.DespachoQty;
                                    itemQty -= tempQty;

                                    var inRelated = new MS_BillSourceRelated()
                                    {
                                        Id = Guid.NewGuid(),
                                        TenantId = userToken.TenantId,
                                        BillId = entity.Id,
                                        BillDetailId = item.Id,
                                        SourceBillId = orderDetail.KeyId,
                                        SourceBillDetailId = orderDetail.RecordId,
                                        SourceType = entity.SourceBillType,
                                        Status = 1,
                                        BillType = entity.BillType,
                                        Qty = tempQty,
                                        Wieght = 0,
                                    };
                                    billSourceRelateds.Add(inRelated);
                                    //updOrderDetails.Add(orderDetail);
                                }
                                if (itemQty > 0)
                                {
                                    result.IsSuccess = false;
                                    result.Msg = "订单退库数已超订单数";
                                    return result;
                                    var inOrderDetails = new SALE_OrderDetail();
                                    var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = entity.Id, BillDetailId = item.Id, BillType = entity.BillType, SourceType = entity.SourceBillType, Status = 1, TenantId = entity.TenantId, Qty = itemQty, Wieght = 0, };
                                    if (orderDetails.Count > 0)
                                    {
                                        inOrderDetails = orderDetails.OrderByDescending(t => t.CreateTime).First();
                                        inOrderDetails.RecordId = Guid.NewGuid();
                                        inOrderDetails.Qty = (int)itemQty;
                                        inOrderDetails.DescQty = 0;
                                        inOrderDetails.DespachoQty -= entity.SourceBillType == 25 ? (int)itemQty : 0;
                                        inOrderDetails.EntradaQty += Convert.ToInt32(itemQty);
                                        inOrderDetails.Total = inOrderDetails.Price * inOrderDetails.Qty;
                                        inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;
                                    }
                                    else
                                    {
                                        var sALE_Order = _client.Queryable<SALE_Order, MS_BillSourceRelated>((a, b) => new object[] { a.KeyId == b.SourceBillId }).Where((a, b) => b.BillId == entity.Id).OrderBy((a, b) => a.BillDate, OrderByType.Desc).First();
                                        inOrderDetails = new SALE_OrderDetail()
                                        {
                                            RecordId = Guid.NewGuid(),
                                            KeyId = sALE_Order.KeyId,
                                            SizeName = item.SizeName,
                                            ColorName = item.ColorName,
                                            Creator = userToken.UserId,
                                            CreateTime = DateTime.Now,
                                            TenantId = entity.TenantId,
                                            CalQty = Convert.ToInt32(itemQty),
                                            CustSalesMan = "",
                                            CustStyleNo = "",
                                            DealQty = Convert.ToInt32(itemQty),
                                            DescQty = 0,
                                            DespachoQty = 0,
                                            Discount = 100,
                                            EntradaQty = Convert.ToInt32(itemQty),
                                            MaterialId = item.MaterialId,
                                            MaterialName = item.MaterialName,
                                            MaterialNo = item.MaterialNo,
                                            PhotoUrl = item.PhotoUrl,
                                            Price = item.Price,
                                            Qty = Convert.ToInt32(itemQty),
                                            OrgPrice = item.Price,
                                            DealTotal = itemQty * item.Price,
                                            OrgTotal = itemQty * item.Price,
                                            RecordType = 1,
                                            Remark = "",
                                            remPrice = item.Price,
                                            Tax = item.Tax,
                                            Taxprice = item.Tax * itemQty * item.Price / 100,
                                            Total = itemQty * item.Price,
                                            UnitName = item.UnitName,
                                        };
                                        inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;
                                        inOrderDetailLists.Add(inOrderDetails);
                                        inLogs.Add(new OperateLogModel
                                        {
                                            TenantId = userToken.TenantId,
                                            BillId = inOrderDetails.KeyId,
                                            Creator = userToken.UserId,
                                            CreatorName = "",
                                            BillType = Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.销售),
                                            BillNo = entity.BillNo,
                                            RelationType = "",
                                            RelationBillNo = "",
                                            CreateTime = DateTime.Now,
                                            CommandName = $"销售单详情",
                                            TableName = inOrderDetails.GetType().Name,
                                            Remark = "销售单新增销售明细",
                                            NewValue = JsonSerializerHelper.Encode(inOrderDetails),
                                        });
                                    }
                                    inRelated.SourceBillDetailId = inOrderDetails.RecordId;
                                    inRelated.SourceBillId = inOrderDetails.KeyId;
                                    billSourceRelateds.Add(inRelated);
                                }
                            }
                        }
                        details.AddRange(addDetails);
                        foreach (var item in details)
                        {
                            if (entity.BillType == 40 /*&& entity.Status == 3*/)
                            {
                                item.DespachoQty = item.Qty;
                                item.DescQty = 0;
                            }
                            else if (entity.BillType == 41/* && entity.Status == 3*/)
                            {
                                item.EntradaQty = item.Qty;
                                item.DescQty = 0;
                            }
                        }

                        await _client.Insertable(details).ExecuteCommandAsync();

                        await _client.Updateable(orderDetails).ExecuteCommandAsync();
                        await _client.Insertable(inOrderDetailLists).ExecuteCommandAsync();
                        await _client.Insertable(billSourceRelateds).ExecuteCommandAsync();

                        var saleIds = orderDetails.Select(t => t.KeyId).Distinct().ToList();

                        foreach (var item in saleIds)
                        {
                            await _client.Ado.UseStoredProcedure().ExecuteCommandAsync("Pro_SaleOrder_SyncQty", new { Id = item });
                        }

                        new Task(() =>
                        {
                            foreach (var item in inLogs)
                            {
                                OperateLog(item);
                            }
                        }).Start();
                        break;
                    case 3:
                        result.IsSuccess = false;
                        result.Msg = $"调拨相关单据不支持新增明细";
                        return result;
                        break;
                    case 4:
                        result.IsSuccess = false;
                        result.Msg = $"生产相关单据不支持新增明细";
                        return result;
                        break;
                    case 5:
                        result.IsSuccess = false;
                        result.Msg = $"委外相关单据不支持新增明细";
                        return result;
                        break;
                    case 6:
                        result.IsSuccess = false;
                        result.Msg = $"盘点相关单据不支持新增明细";
                        return result;
                        break;
                    case 7:
                        result.IsSuccess = false;
                        result.Msg = $"产品设计相关单据不支持新增明细";
                        return result;
                        break;
                    case 8:
                        result.IsSuccess = false;
                        result.Msg = $"委外收发相关单据不支持新增明细";
                        return result;
                        break;
                    default:
                        foreach (var item in details)
                        {
                            if (entity.BillType == 40 && entity.Status == 3)
                            {
                                item.DespachoQty = item.Qty;
                                item.DescQty = 0;
                            }
                            else if (entity.BillType == 41 && entity.Status == 3)
                            {
                                item.EntradaQty = item.Qty;
                                item.DescQty = 0;
                            }
                        }
                        break;
                }
            //switch (entity.Status)
            //{
            //    case 0:
            //    case 1:
            //    case 2:
            //    case 5:
            //        _client.Updateable(entity).ExecuteCommand();
            //        _client.Insertable(details).ExecuteCommand();
            //        result.IsSuccess = true;
            //        result.Msg = "操作成功";
            //        result = _stocksBal.ModifyStockQty(userToken, details.Select(t => t.MaterialId).ToList()).Result;
            //        return result;
            //        break;
            //    case 3:
            //        break;
            //    default:
            //        break;
            //}

            _client.Updateable(entity).ExecuteCommand();

            _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Stroge_SyncQty", new { Id = entity.Id });
            await _stocksBal.ModifyStockQty(userToken, details.Select(t => t.MaterialId).Distinct().ToList());
            result.IsSuccess = true;

            new Task(() =>
            {
                OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"修改{(entity.BillType == 40 ? "出库" : "入库")}单",
                    TableName = entity.GetType().Name,
                    Remark = $"新增{(entity.BillType == 40 ? "出库" : "入库")}单明细",
                    NewValue = JsonSerializerHelper.Encode(details),
                });
            }).Start();

            return result;
        }
        public async Task<BalResult> ModifyDetail(UserToken userToken, MSStrogeDetailModifyModel model)
        {
            var result = new BalResult();
            var detail = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.Id == model.Id).First();
            var addDetails = new List<MS_StrogeDetail>();
            var entity = _client.Queryable<MS_Stroge>().Where(a => a.Id == detail.StrogeId).First();
            var OldValue = JsonSerializerHelper.Encode(detail);
            if (entity.SourceBillType / 10 == 6)
            {
                result.IsSuccess = false;
                result.Msg = "盘点单出入库不支持修改";
                return result;
            }
            var barcodeAny = _client.Queryable<MS_BarCodeTrack>().Where(t => t.BillId == entity.Id).Any();
            if (barcodeAny)
            {
                result.IsSuccess = false;
                result.Msg = $"扫码{(entity.BillType == 40 ? "出" : "入")}库单据不支持修改";
                return result;
            }
            if (model.Qty < 0)
            {
                var orgDetails = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.StrogeId == detail.StrogeId && t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName)
                    .GroupBy(t => new { t.MaterialId, t.ColorName, t.SizeName, })
                    .Select(t => new { t.MaterialId, t.ColorName, t.SizeName, Qty = SqlFunc.AggregateSum(SqlFunc.IIF(t.Qty < 0, t.Qty, SqlFunc.IIF(entity.BillType == 40, t.DespachoQty, t.EntradaQty))), })
                    .ToList();
                var descQty = orgDetails.Sum(t => t.Qty);
                if (model.Qty + descQty < 0)
                {
                    return new BalResult(false, $"{detail.MaterialNo}{detail.ColorName}{detail.SizeName}原单据合计数为{descQty}，修改数不可为{model.Qty}");
                }
            }
            var IsStrogeToSaleOrder = false;
            if (entity.BillType == 40 && entity.SourceBillType / 10 == 2)
            {
                var flowSet = RefitExtensions.For<ITenantSysSetAPI>(Appsettings.BaseUrl).GetTenantSet(new Data.ViewModel.SYS.Set.SysSetSearchModel() { SetTypeKey = "BillFlow", ItemKey = "FlowSet", DetailKey = "IsStrogeToSaleOrder" }, userToken.Token).Result;
                if (flowSet != null)
                {
                    if (flowSet?.SetTenantValue?.SetItemValue.ToLower() == "true")
                    {
                        IsStrogeToSaleOrder = true;
                    }
                }
            }
            var orgQty = detail.Qty;
            var newQty = model.Qty;
            var orgWeight = detail.Weight;
            var newWeight = model.Weight;

            var orgTotal = detail.Total;

            var diffQty = orgQty - newQty;
            var calQty = orgQty - newQty;
            if (entity.BillType == 40)
            {
                diffQty = -diffQty;
            }
            var stockDetail = _client.Queryable<MS_StockDetail>()
                        .Where(t => t.TenantId == userToken.TenantId
                        && t.MaterialId == model.MaterialId
                        && t.DeptId == entity.DepotId
                        && SqlFunc.IsNull(t.PositionNo, "") == (detail.PositionNo ?? "")
                        && t.VatNo == model.VatNo
                        && t.ColorName == model.ColorName && t.SizeName == model.SizeName && t.SpecsName == model.Specs).First();

            var dept = await _client.Queryable<HR_Dept>().Where(t => t.DeptID == entity.DepotId).FirstAsync();
            if ((entity.DepotStatus == 2 || entity.DepotStatus == 5) && dept.IsVerifyStock && stockDetail != null && stockDetail.TotalQty < diffQty)
            {
                result.IsSuccess = false;
                result.Msg = "库存不足";
                return result;
            }

            if (entity.BillType == 40 && entity.DepotStatus == 5/* && entity.IsAutoBuild*/)
            {
                if (diffQty > 0)
                {
                    if (_client.Queryable<HR_Dept>().Where(t => t.DeptID == entity.DepotId).First().IsVerifyStock)
                    {
                        var stockAny = _client.Queryable<MS_StockDetail>().Where(t => t.TenantId == userToken.TenantId && t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.SpecsName == detail.Specs && t.VatNo == detail.VatNo && t.TotalQty >= diffQty).Any();
                        if (!stockAny)
                        {
                            result.IsSuccess = false;
                            result.Msg = "库存数不足，修改失败";
                            return result;
                        }
                    }
                }
                detail.DescQty = 0;
                detail.DespachoQty = newQty;
                entity.DespachoQty = entity.DespachoQty - orgQty + newQty;
                entity.TotalQty = entity.TotalQty - orgQty + newQty;
            }
            else if (entity.BillType == 41 && entity.DepotStatus == 2/* && entity.IsAutoBuild*/)
            {
                if (diffQty > 0)
                {
                    if (_client.Queryable<HR_Dept>().Where(t => t.DeptID == entity.DepotId).First().IsVerifyStock)
                    {
                        var stockAny = _client.Queryable<MS_StockDetail>().Where(t => t.TenantId == userToken.TenantId && t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.SpecsName == detail.Specs && t.VatNo == detail.VatNo && t.TotalQty >= diffQty).Any();
                        if (!stockAny)
                        {
                            result.IsSuccess = false;
                            result.Msg = "库存数不足，修改失败";
                            return result;
                        }
                    }
                }
                detail.DescQty = 0;
                detail.EntradaQty = newQty;
                entity.EntradaQty = entity.EntradaQty - orgQty + newQty;
                entity.TotalQty = entity.TotalQty - orgQty + newQty;
            }
            else
            {
                detail.DescQty = detail.DescQty - orgQty + newQty;
                entity.DescQty = entity.DescQty - orgQty + newQty;
                entity.TotalQty = entity.TotalQty - orgQty + newQty;
            }
            detail.Price = model.Price;
            detail.Total = detail.Qty * (1 + detail.Tax / 100) * detail.Price;
            detail.Qty = newQty;
            detail.VatNo = model.VatNo;
            detail.ColorName = model.ColorName;
            detail.SizeName = model.SizeName;
            detail.Specs = model.Specs;

            var billSourceRelateds = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.BillDetailId == detail.Id).ToList();
            var sourceBillDetailIds = billSourceRelateds.Select(t => t.SourceBillDetailId).ToList();
            var sourceBillIds = billSourceRelateds.Select(t => t.SourceBillId).ToList();

            var client = _client;
            //client.BeginTran();

            var _stocksBal = new StocksBal(_capBus);
            try
            {
                result.IsSuccess = true;
                switch (entity.Status)
                {
                    case 0:
                    case 1:
                    case 2:
                    case 5:
                        client.Updateable(entity).ExecuteCommand();
                        client.Updateable(detail).ExecuteCommand();
                        result.IsSuccess = true;
                        result.Msg = "操作成功";
                        result = _stocksBal.ModifyStockQty(userToken, new List<Guid>() { detail.MaterialId, }).Result;
                        return result;
                        break;
                    case 3:
                        var sbt = entity.SourceBillType / 10;
                        switch (sbt)
                        {
                            case 1:
                                var purchaseDetails = _client.Queryable<MS_PurchaseDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.RecordId)).ToList();
                                var purs = _client.Queryable<MS_Purchase>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.KeyId)).ToList();

                                foreach (var item in billSourceRelateds)
                                {
                                    var detailCols = purchaseDetails.Where(t => t.RecordId == item.SourceBillDetailId).First();
                                    var purCols = purs.Where(t => t.KeyId == item.SourceBillId).First();
                                    if (entity.SourceBillType == 11)
                                    {
                                        detailCols.EntradaQty -= calQty;
                                        detailCols.DescQty = detailCols.Qty - detailCols.EntradaQty;
                                        purCols.DescQty -= calQty;
                                        purCols.EntradaQty = purCols.TotalQty - purCols.EntradaQty;
                                        item.Qty = newQty;

                                        if (purCols.EntradaQty == 0)
                                            purCols.DepotStatus = 0;
                                        else if (purCols.EntradaQty > 0 && purCols.EntradaQty < purCols.TotalQty)
                                            purCols.DepotStatus = 1;
                                        else if (purCols.EntradaQty == purCols.TotalQty)
                                            purCols.DepotStatus = 2;
                                        else if (purCols.EntradaQty > purCols.TotalQty)
                                            purCols.DepotStatus = 7;
                                    }
                                    else if (entity.SourceBillType == 14)
                                    {
                                        detailCols.EntradaQty += calQty;
                                        detailCols.DespachoQty -= calQty;
                                        detailCols.DescQty = detailCols.Qty - detailCols.EntradaQty;
                                        purCols.EntradaQty += calQty;
                                        purCols.DespachoQty -= calQty;
                                        purCols.DescQty = purCols.TotalQty - purCols.EntradaQty;

                                        if (purCols.DespachoQty == 0)
                                            purCols.DepotStatus = 3;
                                        else if (purCols.DespachoQty > 0 && purCols.DespachoQty < purCols.TotalQty)
                                            purCols.DepotStatus = 4;
                                        else if (purCols.DespachoQty == purCols.TotalQty)
                                            purCols.DepotStatus = 5;
                                        else if (purCols.DespachoQty > purCols.TotalQty)
                                            purCols.DepotStatus = 6;
                                    }
                                }
                                _client.Updateable(purchaseDetails).ExecuteCommand();
                                foreach (var item in purs)
                                {
                                    _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Purchase_SyncQty", new { Id = item.KeyId });
                                }
                                break;
                            case 2:
                                var orderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                    .Where((a, b) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.RecordId))
                                    .OrderBy((a, b) => new { b.IsDayEnd, a.CreateTime })
                                    .ToList();
                                //var sales = _client.Queryable<SALE_Order>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.KeyId)).ToList();
                                var inBillSourceRelateds = new List<MS_BillSourceRelated>();
                                var inOrderDetailLists = new List<SALE_OrderDetail>();
                                var inLogs = new List<OperateLogModel>();

                                if (entity.SourceBillType == 22 || entity.SourceBillType == 25)
                                {
                                    var orderDetailTotalQty = orderDetails.Sum(t => t.Qty);
                                    if (!IsStrogeToSaleOrder && orderDetailTotalQty < newQty)
                                    {
                                        result.IsSuccess = false;
                                        result.Msg = "订单出库数已超订单数，不允许增加商品";
                                        return result;
                                    }
                                }
                                else
                                {
                                    var orderDetailTotalQty = orderDetails.Sum(t => t.Qty);
                                    if (orderDetailTotalQty < newQty)
                                    {
                                        result.IsSuccess = false;
                                        result.Msg = "订单退库数已超订单数";
                                        return result;
                                    }
                                }
                                if (calQty < 0)
                                {
                                    if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                                    {
                                        var orderDetailTemps = orderDetails.Where(t => t.Qty - t.DespachoQty > 0).ToList();
                                        //var itemQty = Math.Abs(calQty);
                                        foreach (var item in orderDetailTemps)
                                        {
                                            if (calQty == 0)
                                                break;
                                            var tempQty = Math.Abs(calQty) > item.Qty - item.DespachoQty ? item.Qty - item.DespachoQty : calQty;
                                            var related = billSourceRelateds.Where(t => t.SourceBillDetailId == item.RecordId).First();
                                            related.Qty -= tempQty;
                                            item.DespachoQty -= (int)tempQty;
                                            item.DescQty = item.Qty - item.DespachoQty;
                                            calQty = calQty - tempQty;
                                        }
                                        if (calQty < 0)
                                        {
                                            var orgOrderDetails = _client.Queryable<SALE_OrderDetail>().Where(t => t.MaterialId == detail.MaterialId && detail.ColorName == t.ColorName && t.SizeName == detail.SizeName && t.Qty - t.DespachoQty > 0).ToList();
                                            var itemQty = Math.Abs(calQty);
                                            foreach (var item in orgOrderDetails)
                                            {
                                                if (itemQty == 0)
                                                    break;
                                                var tempQty = itemQty > item.Qty - item.DespachoQty ? item.Qty - item.DespachoQty : itemQty;


                                                Guid tempDetailId = detail.Id;
                                                if (item.Price != item.Price || item.Tax != item.Tax)
                                                {
                                                    if (!addDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Price == item.Price && t.Tax == item.Tax).Any())
                                                    {//价格不同税率不同且没有分解新增项
                                                        item.Price = item.Price;
                                                        item.Tax = item.Tax;
                                                        item.DespachoQty += (int)tempQty;
                                                        item.DescQty = item.Qty - item.DespachoQty;
                                                    }
                                                    else
                                                    {
                                                        if (addDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Price == item.Price && t.Tax == item.Tax).Any())
                                                        {
                                                            var temp = addDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName && t.Price == item.Price && t.Tax == item.Tax).First();
                                                            temp.Qty += tempQty;
                                                            tempDetailId = temp.Id;
                                                        }
                                                        else
                                                        {
                                                            var temp = ObjectHelper.Mapper<MS_StrogeDetail, MS_StrogeDetail>(detail);
                                                            temp.Id = Guid.NewGuid();
                                                            tempDetailId = temp.Id;
                                                            temp.Price = item.Price;
                                                            temp.Tax = item.Tax;
                                                            temp.Qty = tempQty;
                                                            temp.Taxprice = tempQty * item.Tax * item.Price / 100;

                                                            addDetails.Add(temp);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    item.DespachoQty += (int)tempQty;
                                                    item.DescQty = item.Qty - item.DespachoQty;
                                                }
                                                //item.DespachoQty += (int)tempQty;
                                                //item.DescQty = item.Qty - item.DespachoQty;
                                                itemQty -= tempQty;

                                                var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = entity.Id, BillDetailId = detail.Id, BillType = entity.BillType, SourceType = entity.SourceBillType, Status = 1, TenantId = entity.TenantId, Qty = calQty, Wieght = 0, };

                                                inRelated.SourceBillDetailId = item.RecordId;
                                                inRelated.SourceBillId = item.KeyId;
                                                inBillSourceRelateds.Add(inRelated);

                                                orderDetails.Add(item);
                                            }
                                            calQty = itemQty;
                                        }
                                        if (calQty > 0)
                                        {
                                            var keyIds = orderDetails.Select(t => t.KeyId).Distinct().ToList();
                                            var orders = _client.Queryable<SALE_Order>().Where(a => keyIds.Contains(a.KeyId) && a.IsDayEnd == true).ToList();
                                            if (orders.Count == 0)
                                            {
                                                result.IsSuccess = false;
                                                result.Msg = "出货数大于订单数，不允许保存！";
                                                return result;
                                            }
                                            keyIds = orders.Select(t => t.KeyId).Distinct().ToList();
                                            var tempOrderDetails = orderDetails.Where(t => keyIds.Contains(t.KeyId)).OrderByDescending(t => t.CreateTime).First();
                                            tempOrderDetails.Qty += Convert.ToInt32(calQty);
                                            tempOrderDetails.DealQty += Convert.ToInt32(calQty);
                                            tempOrderDetails.DespachoQty += Convert.ToInt32(calQty);
                                            tempOrderDetails.CalQty += Convert.ToInt32(calQty);

                                            var tempRelated = billSourceRelateds.Where(t => t.SourceBillDetailId == tempOrderDetails.RecordId).First();
                                            tempRelated.Qty += Convert.ToInt32(calQty);
                                            inLogs.Add(new OperateLogModel
                                            {
                                                TenantId = userToken.TenantId,
                                                BillId = tempOrderDetails.KeyId,
                                                Creator = userToken.UserId,
                                                CreatorName = "",
                                                BillType = Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.销售),
                                                BillNo = entity.BillNo,
                                                RelationType = "",
                                                RelationBillNo = "",
                                                CreateTime = DateTime.Now,
                                                CommandName = $"销售单详情",
                                                TableName = tempOrderDetails.GetType().Name,
                                                Remark = "修改出货单同步修改销售明细",
                                                NewValue = JsonSerializerHelper.Encode(tempOrderDetails),
                                            });
                                        }
                                    }
                                    else
                                    {
                                        orderDetails = orderDetails.Where(t => t.Qty - t.EntradaQty > 0).OrderByDescending(t => t.CreateTime).ToList();
                                        var itemQty = Math.Abs(calQty);
                                        foreach (var item in orderDetails)
                                        {
                                            if (itemQty == 0)
                                                break;
                                            var tempQty = itemQty > item.Qty - item.EntradaQty ? item.Qty - item.EntradaQty : itemQty;
                                            var related = billSourceRelateds.Where(t => t.SourceBillDetailId == item.RecordId).First();
                                            related.Qty += tempQty;

                                            item.EntradaQty += (int)tempQty;
                                            itemQty -= tempQty;
                                        }
                                    }
                                }
                                else if (calQty > 0)
                                {
                                    if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                                    {
                                        orderDetails = orderDetails.Where(t => t.DespachoQty > 0).OrderByDescending(t => t.CreateTime).ToList();
                                        var itemQty = Math.Abs(calQty);
                                        foreach (var item in orderDetails)
                                        {
                                            if (itemQty == 0)
                                                break;
                                            var tempQty = itemQty > item.DespachoQty ? item.DespachoQty : itemQty;
                                            var related = billSourceRelateds.Where(t => t.SourceBillDetailId == item.RecordId).First();
                                            related.Qty -= tempQty;

                                            item.DespachoQty -= (int)tempQty;
                                            item.DescQty = item.Qty - item.DespachoQty;
                                            itemQty -= tempQty;
                                        }
                                    }
                                    else
                                    {
                                        orderDetails = orderDetails.Where(t => t.EntradaQty > 0).OrderByDescending(t => t.CreateTime).ToList();
                                        var itemQty = Math.Abs(calQty);
                                        foreach (var item in orderDetails)
                                        {
                                            if (itemQty == 0)
                                                break;
                                            var tempQty = itemQty > item.Qty - item.EntradaQty ? item.Qty - item.EntradaQty : itemQty;
                                            var related = billSourceRelateds.Where(t => t.SourceBillDetailId == item.RecordId).First();
                                            related.Qty -= tempQty;

                                            item.EntradaQty -= (int)tempQty;
                                            item.DespachoQty += (int)tempQty;
                                            item.DescQty = item.Qty - item.DespachoQty;
                                            itemQty -= tempQty;
                                        }
                                    }
                                }
                                foreach (var item in addDetails)
                                {
                                    if (entity.BillType == 40)
                                    {
                                        item.DespachoQty = item.Qty;
                                    }
                                    else if (entity.BillType == 41)
                                    {
                                        item.EntradaQty = item.Qty;
                                    }
                                }

                                _client.Insertable(addDetails).ExecuteCommand();

                                _client.Updateable(orderDetails).ExecuteCommand();
                                _client.Insertable(inOrderDetailLists).ExecuteCommand();
                                _client.Insertable(inBillSourceRelateds).ExecuteCommand();
                                var saleIds = orderDetails.Select(t => t.KeyId).Distinct().ToList();
                                foreach (var item in saleIds)
                                {
                                    _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_SaleOrder_SyncQty", new { Id = item });
                                }
                                new Task(() =>
                                {
                                    foreach (var item in inLogs)
                                    {
                                        OperateLog(item);
                                    }
                                }).Start();
                                var sr = _stocksBal.ModifyStockQty(userToken, new List<Guid>() { detail.MaterialId, }).Result;
                                break;
                            case 3:
                                var transfers = _client.Queryable<MS_Transfer>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).First();
                                //var transferDetails = _client.Queryable<MS_TransferDetail>().Where(a => a.TenantId == userToken.TenantId && transfers.Id == a.Id).ToList();
                                var other = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.SourceBillId == transfers.Id).ToList();
                                var billIds = other.Select(t => t.BillId).Distinct().ToList();

                                //_client.Updateable<MS_Stroge>().SetColumns(t => t.Status == -1).SetColumns(t => t.DepotStatus == (entity.BillType == 40 ? 3 : 0)).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => billIds.Contains(t.Id)).ExecuteCommand();
                                //_client.Updateable<MS_StrogeDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => billIds.Contains(t.StrogeId)).ExecuteCommand();

                                //_client.Updateable<MS_Transfer>().SetColumns(t => t.Status == 0).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => sourceBillIds.Contains(t.Id)).ExecuteCommand();
                                //_client.Updateable<MS_TransferDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => sourceBillIds.Contains(t.TransferId)).ExecuteCommand();

                                break;
                            case 4:
                                if (entity.ClassId == 1)
                                {
                                    var produceCalculations = _client.Queryable<MS_ProduceCalculation>().Where((a) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var detailCols = produceCalculations.Where(t => t.Id == item.SourceBillDetailId).First();
                                        if (entity.SourceBillType == 42)
                                        {
                                            detailCols.DespachoQty -= calQty;
                                            detailCols.DescQty = detailCols.ProduceQty - detailCols.DespachoQty;
                                        }
                                        else if (entity.SourceBillType == 43)
                                        {
                                            detailCols.EntradaQty -= calQty;
                                            detailCols.DespachoQty += calQty;
                                            detailCols.DescQty = detailCols.ProduceQty - detailCols.DespachoQty;
                                        }
                                        item.Qty = newQty;
                                    }
                                    var _Produces = _client.Queryable<MS_Produce>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                    var _ProduceCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                    foreach (var item in _Produces)
                                    {
                                        item.Status = item.Status & ~(int)ProduceStatusEnum.Picking & ~(int)ProduceStatusEnum.CompletePick;
                                        var pcAny = _ProduceCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                        var dqQty = _ProduceCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                        if (dqQty > 0)
                                            item.Status = item.Status | (int)ProduceStatusEnum.Picking;
                                        if (pcAny == dqQty)
                                            item.Status = item.Status | (int)ProduceStatusEnum.CompletePick;
                                    }
                                    _client.Updateable(produceCalculations).ExecuteCommand();
                                    _client.Updateable(_Produces).ExecuteCommand();
                                }
                                else if (entity.ClassId == 0)
                                {
                                    var produceDetails = _client.Queryable<MS_ProduceDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                    var produces = _client.Queryable<MS_Produce>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var produceDetail = produceDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                        var produce = produces.Where(t => t.Id == item.SourceBillId).First();
                                        if (entity.SourceBillType == 41)
                                        {
                                            produceDetail.FinishedQty -= calQty;
                                            produceDetail.EntradaQty -= calQty;
                                            produce.FinishedQty -= calQty;
                                            produce.EntradaQty -= calQty;
                                        }
                                        item.Qty = newQty;
                                    }
                                    _client.Updateable(produceDetails).ExecuteCommand();
                                    _client.Updateable(produces).ExecuteCommand();
                                }
                                break;
                            case 5:
                                if (entity.ClassId == 1)
                                {
                                    var outCalculations = _client.Queryable<MS_ProduceCalculation>().Where((a) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var detailCols = outCalculations.Where(t => t.Id == item.SourceBillDetailId).First();
                                        if (entity.SourceBillType == 52)
                                        {
                                            detailCols.DespachoQty -= calQty;
                                            detailCols.DescQty = detailCols.ProduceQty - detailCols.DespachoQty;
                                        }
                                        else if (entity.SourceBillType == 53)
                                        {
                                            detailCols.EntradaQty -= calQty;
                                            detailCols.DespachoQty += calQty;
                                            detailCols.DescQty = detailCols.ProduceQty - detailCols.DespachoQty;
                                        }
                                        item.Qty = newQty;
                                    }
                                    var _Outsourcs = _client.Queryable<MS_Outsourc>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                    var _OutSourcCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                    foreach (var item in _Outsourcs)
                                    {
                                        item.Status = item.Status & ~(int)OutsourcStatusEnum.Picking & ~(int)OutsourcStatusEnum.CompletePick;
                                        var pcAny = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                        var dqQty = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                        if (dqQty > 0)
                                            item.Status = item.Status | (int)OutsourcStatusEnum.Picking;
                                        if (pcAny == dqQty)
                                            item.Status = item.Status | (int)OutsourcStatusEnum.CompletePick;
                                    }
                                    _client.Updateable(outCalculations).ExecuteCommand();
                                    _client.Updateable(_Outsourcs).ExecuteCommand();
                                }
                                else if (entity.ClassId == 0)
                                {
                                    var outsourcDetails = _client.Queryable<MS_OutsourcDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                    var outsourcs = _client.Queryable<MS_Outsourc>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var outsourcDetail = outsourcDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                        var outsourc = outsourcs.Where(t => t.Id == item.SourceBillId).First();
                                        if (entity.SourceBillType == 51)
                                        {
                                            outsourcDetail.FinishedQty -= calQty;
                                            outsourcDetail.EntradaQty -= calQty;
                                            outsourc.FinishedQty -= calQty;
                                            outsourc.EntradaQty -= calQty;
                                        }
                                        item.Qty = newQty;
                                    }
                                    _client.Updateable(outsourcDetails).ExecuteCommand();
                                    _client.Updateable(outsourcs).ExecuteCommand();
                                }
                                break;
                            case 6:
                                break;
                            case 7:
                                break;
                            case 8:
                                var deliveryDetails = _client.Queryable<MS_DeliveryDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                var deliveries = _client.Queryable<MS_Delivery>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                foreach (var item in billSourceRelateds)
                                {
                                    var deliveryDetail = deliveryDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                    var delivery = deliveries.Where(t => t.Id == item.SourceBillId).First();
                                    if (entity.SourceBillType == 81)
                                    {
                                        deliveryDetail.EntradaQty -= calQty;
                                        deliveryDetail.DescQty = deliveryDetail.Qty - deliveryDetail.EntradaQty;
                                        delivery.EntradaQty -= calQty;
                                        delivery.DescQty = delivery.TotalQty - delivery.EntradaQty;
                                        delivery.Status = 1;
                                        delivery.DepotStatus = 0;
                                    }
                                    item.Qty = newQty;
                                }
                                _client.Updateable(deliveryDetails).ExecuteCommand();
                                _client.Updateable(deliveries).ExecuteCommand();
                                break;
                            default:
                                break;
                        }
                        break;
                    default:
                        break;
                }

                client.Updateable(detail).ExecuteCommand();
                //var details = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.StrogeId == detail.StrogeId).ToList();
                //entity.DescQty = details.Sum(t => t.DescQty);
                //entity.DespachoQty = details.Sum(t => t.DespachoQty);
                //entity.EntradaQty = details.Sum(t => t.EntradaQty);
                //entity.TotalQty = details.Sum(t => t.Qty);
                //entity.Total = details.Sum(t => t.Total);
                //await client.Updateable(entity).ExecuteCommandAsync();

                _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Stroge_SyncQty", new { Id = detail.StrogeId });
                await client.Updateable(billSourceRelateds).ExecuteCommandAsync();

                result = await _stocksBal.ModifyStockQty(userToken, new List<Guid>() { detail.MaterialId });
                //client.CommitTran();

                result.IsSuccess = true;
                result.Msg = "操作成功";

            }
            catch
            {
                //client.RollbackTran();
                throw;
            }
            var matNameList = $"{detail.MaterialName}{detail.ColorName}{detail.SizeName}{detail.Specs}{detail.VatNo}:{detail.Qty}{detail.UnitName}";
            if (result.IsSuccess)
                await OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"修改{(entity.BillType == 40 ? "出库" : "入库")}单",
                    TableName = entity.GetType().Name,
                    Remark = $"修改{(entity.BillType == 40 ? "出库" : "入库")}单明细",
                    OldValue = OldValue,
                    NewValue = JsonSerializerHelper.Encode(detail),
                });
            return result;
        }
        public async Task<BalResult> ModifyRelatedDetail(UserToken userToken, Guid detailId, decimal qty, decimal weight)
        {
            var result = new BalResult();
            var detail = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.Id == detailId).First();
            var entity = _client.Queryable<MS_Stroge>().Where(a => a.Id == detail.StrogeId).First();
            var OldValue = JsonSerializerHelper.Encode(detail);

            var orgQty = detail.Qty;
            var newQty = qty;
            var orgWeight = detail.Weight;
            var newWeight = weight;

            var orgTotal = detail.Total;

            var diffQty = orgQty - newQty;
            var calQty = orgQty - newQty;
            if (entity.BillType == 40)
            {
                diffQty = -diffQty;
            }
            var stockDetail = _client.Queryable<MS_StockDetail>()
                        .Where(t => t.TenantId == userToken.TenantId
                        && t.MaterialId == detail.MaterialId
                        && t.DeptId == entity.DepotId
                        && SqlFunc.IsNull(t.PositionNo, "") == (detail.PositionNo ?? "")
                        && t.VatNo == detail.VatNo
                        && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.SpecsName == detail.Specs).First();

            var dept = await _client.Queryable<HR_Dept>().Where(t => t.DeptID == entity.DepotId).FirstAsync();
            if ((entity.DepotStatus == 2 || entity.DepotStatus == 5) && dept.IsVerifyStock && stockDetail != null && stockDetail.TotalQty < diffQty)
            {
                result.IsSuccess = false;
                result.Msg = "库存不足";
                return result;
            }

            detail.Qty = newQty;
            detail.Total = detail.Price * detail.Qty;
            if (entity.BillType == 40 && entity.DepotStatus >= 5)
                detail.DespachoQty = newQty;
            else if (entity.BillType == 41 && entity.DepotStatus >= 2)
                detail.EntradaQty = newQty;

            var billSourceRelateds = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.BillDetailId == detail.Id).ToList();
            var sourceBillDetailIds = billSourceRelateds.Select(t => t.SourceBillDetailId).ToList();
            var sourceBillIds = billSourceRelateds.Select(t => t.SourceBillId).ToList();
            foreach (var item in billSourceRelateds)
            {
                item.Qty = qty;
            }
            var client = _client;
            //client.BeginTran();
            var _stocksBal = new StocksBal(_capBus);
            try
            {
                result.IsSuccess = true;

                client.Updateable(detail).ExecuteCommand();

                _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Stroge_SyncQty", new { Id = detail.StrogeId });
                await client.Updateable(billSourceRelateds).ExecuteCommandAsync();

                result = await _stocksBal.ModifyStockQty(userToken, new List<Guid>() { detail.MaterialId });

                result.IsSuccess = true;
                result.Msg = "操作成功";
            }
            catch
            {
                //client.RollbackTran();
                throw;
            }
            var matNameList = $"{detail.MaterialName}{detail.ColorName}{detail.SizeName}{detail.Specs}{detail.VatNo}:{detail.Qty}{detail.UnitName}";
            if (result.IsSuccess)
                await OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"修改{(entity.BillType == 40 ? "出库" : "入库")}单",
                    TableName = entity.GetType().Name,
                    Remark = $"修改{(entity.BillType == 40 ? "出库" : "入库")}单明细",
                    OldValue = OldValue,
                    NewValue = JsonSerializerHelper.Encode(detail),
                });
            return result;
        }
        /// <summary>
        /// 删除整单
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public BalResult DeleteBill(UserToken userToken, Guid Id, bool isForce = false)
        {
            var result = new BalResult();

            try
            {
                if (_client.Queryable<MS_Stroge>().Any(t => t.TenantId == userToken.TenantId && t.Id == Id))
                {
                    var entity = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id).First();
                    if (entity.Status == -1)
                    {
                        result.IsSuccess = false;
                        result.Msg = "单据已删除";
                        return result;
                    }
                    //if (entity.IsAutoBuild/* && entity.SourceBillType != 52*/&& !isForce)
                    //{
                    //    result.IsSuccess = false;
                    //    result.Msg = "自动生成单据不可删除！";
                    //    return result;
                    //}
                    //if (entity.Status == 3 /*&& entity.SourceBillType != 52*/&& !isForce)
                    //{
                    //    result.IsSuccess = false;
                    //    result.Msg = "已完成单据不可删除！";
                    //    return result;
                    //}
                    var barCodeTracks = _client.Queryable<MS_BarCodeTrack>().Where(t => t.BillId == entity.Id).ToList();
                    var barCodes = _client.Queryable<MS_BarCode>().Where(t => t.BillId == entity.Id).ToList();
                    if (barCodeTracks.Count != barCodes.Count)
                    {
                        var bs = barCodes.Select(t => t.BarCode).Except(barCodeTracks.Select(t => t.BarCode)).ToList();
                        return new BalResult(false, $"条码{string.Join(",", bs)}已进入下一流程，无法删除");
                    }
                    var details = _client.Queryable<MS_StrogeDetail>().Where(a => a.TenantId == userToken.TenantId && a.StrogeId == entity.Id).ToList();
                    var billSourceRelateds = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.BillId == entity.Id).ToList();
                    var sourceBillDetailIds = billSourceRelateds.Select(t => t.SourceBillDetailId).ToList();
                    var sourceBillIds = billSourceRelateds.Select(t => t.SourceBillId).ToList();
                    var billDetailIds = billSourceRelateds.Select(t => t.BillDetailId).ToList();
                    var billIds = billSourceRelateds.Select(t => t.BillId).ToList();

                    var _stocksBal = new StocksBal(_capBus);
                    switch (entity.Status)
                    {
                        case 0:
                        case 1:
                        case 2:
                        case 5:
                            _client.Updateable<MS_Stroge>().SetColumns(t => t.Status == -1).SetColumns(t => t.DepotStatus == (entity.BillType == 40 ? 3 : 0)).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).SetColumns(t => t.DepotStatus == SqlFunc.IIF(t.BillType == 40, 3, 0)).Where(t => t.Id == Id).ExecuteCommand();
                            _client.Updateable<MS_StrogeDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => t.StrogeId == Id).ExecuteCommand();
                            result.IsSuccess = true;
                            result.Msg = "操作成功";
                            result = _stocksBal.ModifyStockQty(userToken, details.Select(t => t.MaterialId).ToList()).Result;
                            return result;
                            break;
                        case 3:
                            var sbt = entity.SourceBillType / 10;
                            switch (sbt)
                            {
                                case 1:
                                    var purchaseDetails = _client.Queryable<MS_PurchaseDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.RecordId)).ToList();
                                    var purs = _client.Queryable<MS_Purchase>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.KeyId)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var detailCols = purchaseDetails.Where(t => t.RecordId == item.SourceBillDetailId).First();
                                        var purCols = purs.Where(t => t.KeyId == item.SourceBillId).First();
                                        if (entity.SourceBillType == 11)
                                        {
                                            detailCols.DescQty += item.Qty;
                                            detailCols.EntradaQty -= item.Qty;
                                            purCols.DescQty += item.Qty;
                                            purCols.EntradaQty -= item.Qty;

                                            if (purCols.EntradaQty == 0)
                                                purCols.DepotStatus = 0;
                                            else if (purCols.EntradaQty > 0 && purCols.EntradaQty < purCols.TotalQty)
                                                purCols.DepotStatus = 1;
                                            else if (purCols.EntradaQty == purCols.TotalQty)
                                                purCols.DepotStatus = 2;
                                            else if (purCols.EntradaQty > purCols.TotalQty)
                                                purCols.DepotStatus = 7;
                                        }
                                        else if (entity.SourceBillType == 14)
                                        {
                                            detailCols.DescQty += item.Qty;
                                            detailCols.EntradaQty += item.Qty;
                                            detailCols.DespachoQty -= item.Qty;
                                            purCols.DescQty += item.Qty;
                                            purCols.EntradaQty += item.Qty;
                                            purCols.DespachoQty -= item.Qty;

                                            if (purCols.DespachoQty == 0)
                                                purCols.DepotStatus = 3;
                                            else if (purCols.DespachoQty > 0 && purCols.DespachoQty < purCols.TotalQty)
                                                purCols.DepotStatus = 4;
                                            else if (purCols.DespachoQty == purCols.TotalQty)
                                                purCols.DepotStatus = 5;
                                            else if (purCols.DespachoQty > purCols.TotalQty)
                                                purCols.DepotStatus = 6;
                                        }
                                    }
                                    _client.Updateable(purchaseDetails).ExecuteCommand();
                                    foreach (var item in purs)
                                    {
                                        _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Purchase_SyncQty", new { Id = item.KeyId });
                                    }
                                    break;
                                case 2:
                                    var orderDetails = _client.Queryable<SALE_OrderDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.RecordId)).ToList();
                                    var sales = _client.Queryable<SALE_Order>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.KeyId)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var orderDetail = orderDetails.Where(t => t.RecordId == item.SourceBillDetailId).First();
                                        var sale = sales.Where(t => t.KeyId == item.SourceBillId).First();
                                        if (entity.SourceBillType == 22 || entity.SourceBillType == 25)
                                        {
                                            orderDetail.DescQty += Convert.ToInt32(item.Qty);
                                            orderDetail.DespachoQty -= Convert.ToInt32(item.Qty);
                                            sale.DescQty += Convert.ToInt32(item.Qty);
                                            sale.DespachoQty -= Convert.ToInt32(item.Qty);

                                            if (sale.DespachoQty == 0)
                                                sale.DepotStatus = 3;
                                            else if (sale.DespachoQty > 0 && sale.DespachoQty < sale.TotalQty)
                                                sale.DepotStatus = 4;
                                            else if (sale.DespachoQty == sale.TotalQty)
                                                sale.DepotStatus = 5;
                                            else if (sale.DespachoQty > sale.TotalQty)
                                                sale.DepotStatus = 6;
                                        }
                                        else if (entity.SourceBillType == 23)
                                        {
                                            orderDetail.DescQty += Convert.ToInt32(item.Qty);
                                            orderDetail.EntradaQty += Convert.ToInt32(item.Qty);
                                            orderDetail.DespachoQty -= Convert.ToInt32(item.Qty);
                                            sale.DescQty += Convert.ToInt32(item.Qty);
                                            sale.EntradaQty += Convert.ToInt32(item.Qty);
                                            sale.DespachoQty -= Convert.ToInt32(item.Qty);

                                            if (sale.EntradaQty == 0)
                                                sale.DepotStatus = 0;
                                            else if (sale.EntradaQty > 0 && sale.EntradaQty < sale.TotalQty)
                                                sale.DepotStatus = 1;
                                            else if (sale.EntradaQty == sale.TotalQty)
                                                sale.DepotStatus = 2;
                                            else if (sale.EntradaQty > sale.TotalQty)
                                                sale.DepotStatus = 7;
                                        }
                                    }
                                    _client.Updateable(orderDetails).ExecuteCommand();

                                    foreach (var item in sales)
                                    {
                                        _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_SaleOrder_SyncQty", new { Id = item.KeyId });
                                    }
                                    break;
                                case 3:
                                    var transfers = _client.Queryable<MS_Transfer>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).First();
                                    //var transferDetails = _client.Queryable<MS_TransferDetail>().Where(a => a.TenantId == userToken.TenantId && transfers.Id == a.Id).ToList();
                                    var other = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.SourceBillId == transfers.Id).ToList();
                                    billIds = other.Select(t => t.BillId).Distinct().ToList();

                                    _client.Updateable<MS_Stroge>().SetColumns(t => t.Status == -1).SetColumns(t => t.DepotStatus == (entity.BillType == 40 ? 3 : 0)).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => billIds.Contains(t.Id)).ExecuteCommand();
                                    _client.Updateable<MS_StrogeDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => billIds.Contains(t.StrogeId)).ExecuteCommand();

                                    _client.Updateable<MS_Transfer>().SetColumns(t => t.Status == 0).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => sourceBillIds.Contains(t.Id)).ExecuteCommand();
                                    _client.Updateable<MS_TransferDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => sourceBillIds.Contains(t.TransferId)).ExecuteCommand();

                                    break;
                                case 4:
                                    if (entity.ClassId == 1)
                                    {
                                        var produceCalculations = _client.Queryable<MS_ProduceCalculation>().Where((a) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();

                                        foreach (var item in billSourceRelateds)
                                        {
                                            var detailCols = produceCalculations.Where(t => t.Id == item.SourceBillDetailId).First();
                                            if (entity.SourceBillType == 42)
                                            {
                                                detailCols.DespachoQty -= item.Qty;
                                                detailCols.DescQty += item.Qty;
                                            }
                                            else if (entity.SourceBillType == 43)
                                            {
                                                detailCols.DescQty += item.Qty;
                                                detailCols.EntradaQty -= item.Qty;
                                                detailCols.DespachoQty -= item.Qty;
                                            }
                                        }
                                        var _Produces = _client.Queryable<MS_Produce>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                        var _ProduceCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                        foreach (var item in _Produces)
                                        {
                                            item.Status = item.Status & ~(int)ProduceStatusEnum.Picking & ~(int)ProduceStatusEnum.CompletePick;
                                            var pcAny = _ProduceCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                            var dqQty = _ProduceCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                            if (dqQty > 0)
                                                item.Status = item.Status | (int)ProduceStatusEnum.Picking;
                                            if (pcAny == dqQty)
                                                item.Status = item.Status | (int)ProduceStatusEnum.CompletePick;
                                        }
                                        _client.Updateable(produceCalculations).ExecuteCommand();
                                        _client.Updateable(_Produces).ExecuteCommand();
                                    }
                                    else if (entity.ClassId == 0)
                                    {
                                        var produceDetails = _client.Queryable<MS_ProduceDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                        var produces = _client.Queryable<MS_Produce>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                        foreach (var item in billSourceRelateds)
                                        {
                                            var produceDetail = produceDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                            var produce = produces.Where(t => t.Id == item.SourceBillId).First();
                                            if (entity.SourceBillType == 41)
                                            {
                                                produceDetail.FinishedQty -= item.Qty;
                                                produceDetail.EntradaQty -= item.Qty;
                                                produce.FinishedQty -= item.Qty;
                                                produce.EntradaQty -= item.Qty;
                                            }
                                        }
                                        _client.Updateable(produceDetails).ExecuteCommand();
                                        _client.Updateable(produces).ExecuteCommand();
                                    }
                                    break;
                                case 5:
                                    if (entity.ClassId == 1)
                                    {
                                        var outCalculations = _client.Queryable<MS_ProduceCalculation>().Where((a) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();

                                        foreach (var item in billSourceRelateds)
                                        {
                                            var detailCols = outCalculations.Where(t => t.Id == item.SourceBillDetailId).First();
                                            if (entity.SourceBillType == 52)
                                            {
                                                detailCols.DespachoQty -= item.Qty;
                                                detailCols.DescQty += item.Qty;
                                            }
                                            else if (entity.SourceBillType == 53)
                                            {
                                                detailCols.DescQty += item.Qty;
                                                detailCols.EntradaQty -= item.Qty;
                                                detailCols.DespachoQty -= item.Qty;
                                            }
                                        }
                                        var _Outsourcs = _client.Queryable<MS_Outsourc>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                        var _OutSourcCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                        foreach (var item in _Outsourcs)
                                        {
                                            item.Status = item.Status & ~(int)OutsourcStatusEnum.Picking & ~(int)OutsourcStatusEnum.CompletePick;
                                            var pcAny = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                            var dqQty = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                            if (dqQty > 0)
                                                item.Status = item.Status | (int)OutsourcStatusEnum.Picking;
                                            if (pcAny == dqQty)
                                                item.Status = item.Status | (int)OutsourcStatusEnum.CompletePick;
                                        }
                                        _client.Updateable(outCalculations).ExecuteCommand();
                                        _client.Updateable(_Outsourcs).ExecuteCommand();
                                    }
                                    else if (entity.ClassId == 0)
                                    {
                                        var outsourcDetails = _client.Queryable<MS_OutsourcDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                        var outsourcs = _client.Queryable<MS_Outsourc>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                        foreach (var item in billSourceRelateds)
                                        {
                                            var outsourcDetail = outsourcDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                            var outsourc = outsourcs.Where(t => t.Id == item.SourceBillId).First();
                                            if (entity.SourceBillType == 51)
                                            {
                                                outsourcDetail.FinishedQty -= item.Qty;
                                                outsourcDetail.EntradaQty -= item.Qty;
                                                outsourc.FinishedQty -= item.Qty;
                                                outsourc.EntradaQty -= item.Qty;
                                            }
                                        }
                                        _client.Updateable(outsourcDetails).ExecuteCommand();
                                        _client.Updateable(outsourcs).ExecuteCommand();
                                    }
                                    break;
                                case 6:
                                    break;
                                case 7:
                                    break;
                                case 8:
                                    var deliveryDetails = _client.Queryable<MS_DeliveryDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                    var deliveries = _client.Queryable<MS_Delivery>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                    foreach (var item in billSourceRelateds)
                                    {
                                        var deliveryDetail = deliveryDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                        var delivery = deliveries.Where(t => t.Id == item.SourceBillId).First();
                                        if (entity.SourceBillType == 81)
                                        {
                                            deliveryDetail.DescQty += item.Qty;
                                            deliveryDetail.EntradaQty -= item.Qty;
                                            delivery.DescQty -= item.Qty;
                                            delivery.EntradaQty -= item.Qty;
                                            delivery.Status = 1;
                                            delivery.DepotStatus = 0;
                                        }
                                    }
                                    _client.Updateable(deliveryDetails).ExecuteCommand();
                                    _client.Updateable(deliveries).ExecuteCommand();
                                    break;
                                default:
                                    break;
                            }

                            _client.Updateable<MS_Stroge>().SetColumns(t => t.Status == -1).SetColumns(t => t.DepotStatus == (entity.BillType == 40 ? 3 : 0)).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => t.Id == Id).ExecuteCommand();
                            _client.Updateable<MS_StrogeDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => t.StrogeId == Id).ExecuteCommand();
                            result.IsSuccess = true;
                            result.Msg = "操作成功";
                            break;
                        case 4:
                            result.IsSuccess = false;
                            result.Msg = "单据已记账，删除失败";
                            return result;
                            break;
                        default:
                            result.IsSuccess = false;
                            result.Msg = "单据状态异常，请联系服务商处理";
                            return result;
                            break;
                    }

                    //var barCodes = _client.Queryable<MS_BarCode>().Where(t => t.TenantId == userToken.TenantId && t.BillId == entity.Id).ToList();
                    foreach (var item in barCodes)
                    {
                        var track = barCodeTracks.Where(t => t.BarCode == item.BarCode).First();
                        item.BillId = track.SourceBillId;
                        item.BillDetailId = track.SourceBillDetailId;
                    }
                    if (barCodes.Count > 0)
                    {
                        _client.Deleteable<MS_BarCodeTrack>().Where(t => t.BillId == entity.Id).ExecuteCommandAsync();
                        _client.Updateable(barCodes).ExecuteCommandAsync();
                    }

                    result = _stocksBal.ModifyStockQty(userToken, details.Select(t => t.MaterialId).ToList()).Result;

                    if (result.IsSuccess && !isForce)
                        new Task(() =>
                        {
                            var details = _client.Queryable<MS_StrogeDetail>().Where(t => t.StrogeId == entity.Id).ToList();
                            OperateLog(new OperateLogModel
                            {
                                TenantId = userToken.TenantId,
                                BillId = entity.Id,
                                Creator = userToken.UserId,
                                CreatorName = userToken.UserName,
                                BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                                BillNo = entity.BillNo,
                                RelationType = "",
                                RelationBillNo = "",
                                CreateTime = DateTime.Now,
                                CommandName = $"删除{(entity.BillType == 40 ? "出库" : "入库")}单",
                                TableName = entity.GetType().Name,
                                Remark = "删除单据",
                                OldValue = JsonSerializerHelper.Encode(new { entity = entity, Details = details })
                            });
                        }).Start();
                }
                else
                {
                    result.IsSuccess = false;
                    result.Msg = "无此单据";
                }
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Msg = ex.Message;
                ex.ToExceptionless().Submit();
            }
            return result;
        }
        /// <summary>
        /// 删除单据明细
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <param name="detailId"></param>
        /// <returns></returns>
        public BalResult DeleteDetails(UserToken userToken, Guid Id, Guid detailId)
        {
            var result = new BalResult();

            try
            {
                if (_client.Queryable<MS_Stroge>().Any(t => t.TenantId == userToken.TenantId && t.Id == Id))
                {
                    var entity = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id).First();
                    //if (entity.IsAutoBuild)
                    //{
                    //    result.IsSuccess = false;
                    //    result.Msg = "自动生成单据不可删除明细！";
                    //    return result;
                    //}
                    //if (entity.Status == 3)
                    //{
                    //    result.IsSuccess = false;
                    //    result.Msg = "已完成单据不可编辑！";
                    //    return result;
                    //}
                    var detail = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.StrogeId == Id && t.Id == detailId).First();

                    var barCodeTracks = _client.Queryable<MS_BarCodeTrack>().Where(t => t.BillDetailId == detail.Id).ToList();
                    var barCodes = _client.Queryable<MS_BarCode>().Where(t => t.BillDetailId == detail.Id).ToList();
                    if (barCodeTracks.Count != barCodes.Count)
                    {
                        var bs = barCodes.Select(t => t.BarCode).Except(barCodeTracks.Select(t => t.BarCode)).ToList();
                        return new BalResult(false, $"条码{string.Join(",", bs)}已进入下一流程，无法删除");
                    }
                    var billSourceRelateds = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.BillDetailId == detail.Id).ToList();
                    var sourceBillDetailIds = billSourceRelateds.Select(t => t.SourceBillDetailId).ToList();
                    var sourceBillIds = billSourceRelateds.Select(t => t.SourceBillId).ToList();
                    //var billDetailIds = billSourceRelateds.Select(t => t.BillDetailId).ToList();
                    //var billIds = billSourceRelateds.Select(t => t.BillId).ToList();

                    var sbt = entity.SourceBillType / 10;

                    switch (sbt)
                    {
                        case 1:
                            var purchaseDetails = _client.Queryable<MS_PurchaseDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.RecordId)).ToList();
                            var purs = _client.Queryable<MS_Purchase>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.KeyId)).ToList();

                            foreach (var item in billSourceRelateds)
                            {
                                var detailCols = purchaseDetails.Where(t => t.RecordId == item.SourceBillDetailId).First();
                                var purCols = purs.Where(t => t.KeyId == item.SourceBillId).First();
                                if (entity.SourceBillType == 11)
                                {
                                    detailCols.DescQty += item.Qty;
                                    detailCols.EntradaQty -= item.Qty;
                                    purCols.DescQty += item.Qty;
                                    purCols.EntradaQty -= item.Qty;

                                    if (purCols.EntradaQty == 0)
                                        purCols.DepotStatus = 0;
                                    else if (purCols.EntradaQty > 0 && purCols.EntradaQty < purCols.TotalQty)
                                        purCols.DepotStatus = 1;
                                    else if (purCols.EntradaQty == purCols.TotalQty)
                                        purCols.DepotStatus = 2;
                                    else if (purCols.EntradaQty > purCols.TotalQty)
                                        purCols.DepotStatus = 7;
                                }
                                else if (entity.SourceBillType == 14)
                                {
                                    detailCols.DescQty += item.Qty;
                                    detailCols.EntradaQty += item.Qty;
                                    detailCols.DespachoQty -= item.Qty;
                                    purCols.DescQty += item.Qty;
                                    purCols.EntradaQty += item.Qty;
                                    purCols.DespachoQty -= item.Qty;

                                    if (purCols.DespachoQty == 0)
                                        purCols.DepotStatus = 3;
                                    else if (purCols.DespachoQty > 0 && purCols.DespachoQty < purCols.TotalQty)
                                        purCols.DepotStatus = 4;
                                    else if (purCols.DespachoQty == purCols.TotalQty)
                                        purCols.DepotStatus = 5;
                                    else if (purCols.DespachoQty > purCols.TotalQty)
                                        purCols.DepotStatus = 6;
                                }
                            }
                            _client.Updateable(purchaseDetails).ExecuteCommand();
                            foreach (var item in purs)
                            {
                                _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Purchase_SyncQty", new { Id = item.KeyId });
                            }
                            break;
                        case 2:
                            var orderDetails = _client.Queryable<SALE_OrderDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.RecordId)).ToList();
                            var sales = _client.Queryable<SALE_Order>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.KeyId)).ToList();

                            foreach (var item in billSourceRelateds)
                            {
                                if (!orderDetails.Where(t => t.RecordId == item.SourceBillDetailId).Any())
                                    continue;
                                var orderDetail = orderDetails.Where(t => t.RecordId == item.SourceBillDetailId).First();
                                var sale = sales.Where(t => t.KeyId == item.SourceBillId).First();
                                if (entity.SourceBillType == 22 || entity.SourceBillType == 25)
                                {
                                    orderDetail.DescQty += Convert.ToInt32(item.Qty);
                                    orderDetail.DespachoQty -= Convert.ToInt32(item.Qty);
                                    sale.DescQty += Convert.ToInt32(item.Qty);
                                    sale.DespachoQty -= Convert.ToInt32(item.Qty);

                                    if (sale.DespachoQty == 0)
                                        sale.DepotStatus = 3;
                                    else if (sale.DespachoQty > 0 && sale.DespachoQty < sale.TotalQty)
                                        sale.DepotStatus = 4;
                                    else if (sale.DespachoQty == sale.TotalQty)
                                        sale.DepotStatus = 5;
                                    else if (sale.DespachoQty > sale.TotalQty)
                                        sale.DepotStatus = 6;
                                }
                                else if (entity.SourceBillType == 23)
                                {
                                    orderDetail.DescQty += Convert.ToInt32(item.Qty);
                                    orderDetail.EntradaQty += Convert.ToInt32(item.Qty);
                                    orderDetail.DespachoQty -= Convert.ToInt32(item.Qty);
                                    sale.DescQty += Convert.ToInt32(item.Qty);
                                    sale.EntradaQty += Convert.ToInt32(item.Qty);
                                    sale.DespachoQty -= Convert.ToInt32(item.Qty);

                                    if (sale.EntradaQty == 0)
                                        sale.DepotStatus = 0;
                                    else if (sale.EntradaQty > 0 && sale.EntradaQty < sale.TotalQty)
                                        sale.DepotStatus = 1;
                                    else if (sale.EntradaQty == sale.TotalQty)
                                        sale.DepotStatus = 2;
                                    else if (sale.EntradaQty > sale.TotalQty)
                                        sale.DepotStatus = 7;
                                }
                            }
                            _client.Updateable(orderDetails).ExecuteCommand();
                            foreach (var item in sales)
                            {
                                _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_SaleOrder_SyncQty", new { Id = item.KeyId });
                            }
                            break;
                        case 3:
                            var transfers = _client.Queryable<MS_Transfer>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).First();
                            //var transferDetails = _client.Queryable<MS_TransferDetail>().Where(a => a.TenantId == userToken.TenantId && transfers.Id == a.Id).ToList();
                            var other = _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == userToken.TenantId && t.SourceBillId == transfers.Id).ToList();
                            var billIds = other.Select(t => t.BillId).Distinct().ToList();

                            _client.Updateable<MS_Stroge>().SetColumns(t => t.Status == -1).SetColumns(t => t.DepotStatus == (entity.BillType == 40 ? 3 : 0)).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => billIds.Contains(t.Id)).ExecuteCommand();
                            _client.Updateable<MS_StrogeDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => billIds.Contains(t.StrogeId)).ExecuteCommand();

                            _client.Updateable<MS_Transfer>().SetColumns(t => t.Status == 0).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.TotalQty).Where(t => sourceBillIds.Contains(t.Id)).ExecuteCommand();
                            _client.Updateable<MS_TransferDetail>().SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).SetColumns(t => t.DescQty == t.Qty).Where(t => sourceBillIds.Contains(t.TransferId)).ExecuteCommand();

                            break;
                        case 4:
                            if (entity.ClassId == 1)
                            {
                                var produceCalculations = _client.Queryable<MS_ProduceCalculation>().Where((a) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();

                                foreach (var item in billSourceRelateds)
                                {
                                    var detailCols = produceCalculations.Where(t => t.Id == item.SourceBillDetailId).First();
                                    if (entity.SourceBillType == 42)
                                    {
                                        detailCols.DespachoQty -= item.Qty;
                                        detailCols.DescQty += item.Qty;
                                    }
                                    else if (entity.SourceBillType == 43)
                                    {
                                        detailCols.DescQty += item.Qty;
                                        detailCols.EntradaQty -= item.Qty;
                                        detailCols.DespachoQty -= item.Qty;
                                    }
                                }
                                var _Produces = _client.Queryable<MS_Produce>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                var _ProduceCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                foreach (var item in _Produces)
                                {
                                    item.Status = item.Status & ~(int)ProduceStatusEnum.Picking & ~(int)ProduceStatusEnum.CompletePick;
                                    var pcAny = _ProduceCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                    var dqQty = _ProduceCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                    if (dqQty > 0)
                                        item.Status = item.Status | (int)ProduceStatusEnum.Picking;
                                    if (pcAny == dqQty)
                                        item.Status = item.Status | (int)ProduceStatusEnum.CompletePick;
                                }
                                _client.Updateable(produceCalculations).ExecuteCommand();
                                _client.Updateable(_Produces).ExecuteCommand();
                            }
                            else if (entity.ClassId == 0)
                            {
                                var produceDetails = _client.Queryable<MS_ProduceDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                var produces = _client.Queryable<MS_Produce>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                foreach (var item in billSourceRelateds)
                                {
                                    var produceDetail = produceDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                    var produce = produces.Where(t => t.Id == item.SourceBillId).First();
                                    if (entity.SourceBillType == 41)
                                    {
                                        produceDetail.FinishedQty -= item.Qty;
                                        produceDetail.EntradaQty -= item.Qty;
                                        produce.FinishedQty -= item.Qty;
                                        produce.EntradaQty -= item.Qty;
                                    }
                                }
                                _client.Updateable(produceDetails).ExecuteCommand();
                                _client.Updateable(produces).ExecuteCommand();
                            }
                            break;
                        case 5:
                            if (entity.ClassId == 1)
                            {
                                var outCalculations = _client.Queryable<MS_ProduceCalculation>().Where((a) => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();

                                foreach (var item in billSourceRelateds)
                                {
                                    var detailCols = outCalculations.Where(t => t.Id == item.SourceBillDetailId).First();
                                    if (entity.SourceBillType == 52)
                                    {
                                        detailCols.DespachoQty -= item.Qty;
                                        detailCols.DescQty += item.Qty;
                                    }
                                    else if (entity.SourceBillType == 53)
                                    {
                                        detailCols.DescQty += item.Qty;
                                        detailCols.EntradaQty -= item.Qty;
                                        detailCols.DespachoQty -= item.Qty;
                                    }
                                }
                                var _Outsourcs = _client.Queryable<MS_Outsourc>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                var _OutSourcCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                foreach (var item in _Outsourcs)
                                {
                                    item.Status = item.Status & ~(int)OutsourcStatusEnum.Picking & ~(int)OutsourcStatusEnum.CompletePick;
                                    var pcAny = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                    var dqQty = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                    if (dqQty > 0)
                                        item.Status = item.Status | (int)OutsourcStatusEnum.Picking;
                                    if (pcAny == dqQty)
                                        item.Status = item.Status | (int)OutsourcStatusEnum.CompletePick;
                                }
                                _client.Updateable(outCalculations).ExecuteCommand();
                                _client.Updateable(_Outsourcs).ExecuteCommand();
                            }
                            else if (entity.ClassId == 0)
                            {
                                var outsourcDetails = _client.Queryable<MS_OutsourcDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                                var outsourcs = _client.Queryable<MS_Outsourc>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                                foreach (var item in billSourceRelateds)
                                {
                                    var outsourcDetail = outsourcDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                    var outsourc = outsourcs.Where(t => t.Id == item.SourceBillId).First();
                                    if (entity.SourceBillType == 51)
                                    {
                                        outsourcDetail.FinishedQty -= item.Qty;
                                        outsourcDetail.EntradaQty -= item.Qty;
                                        outsourc.FinishedQty -= item.Qty;
                                        outsourc.EntradaQty -= item.Qty;
                                    }
                                }
                                _client.Updateable(outsourcDetails).ExecuteCommand();
                                _client.Updateable(outsourcs).ExecuteCommand();
                            }
                            break;
                        case 6:
                            break;
                        case 7:
                            break;
                        case 8:
                            var deliveryDetails = _client.Queryable<MS_DeliveryDetail>().Where(a => a.TenantId == userToken.TenantId && sourceBillDetailIds.Contains(a.Id)).ToList();
                            var deliveries = _client.Queryable<MS_Delivery>().Where(a => a.TenantId == userToken.TenantId && sourceBillIds.Contains(a.Id)).ToList();

                            foreach (var item in billSourceRelateds)
                            {
                                if (deliveryDetails.Where(t => t.Id == item.SourceBillDetailId).Any())
                                {
                                    var deliveryDetail = deliveryDetails.Where(t => t.Id == item.SourceBillDetailId).First();
                                    var delivery = deliveries.Where(t => t.Id == item.SourceBillId).First();
                                    if (entity.SourceBillType == 81)
                                    {
                                        deliveryDetail.DescQty += item.Qty;
                                        deliveryDetail.EntradaQty -= item.Qty;
                                        delivery.DescQty -= item.Qty;
                                        delivery.EntradaQty -= item.Qty;
                                        delivery.Status = 1;
                                        delivery.DepotStatus = 0;
                                    }
                                }
                            }
                            _client.Updateable(deliveryDetails).ExecuteCommand();
                            _client.Updateable(deliveries).ExecuteCommand();
                            break;
                        default:
                            break;
                    }

                    var details = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.StrogeId == Id).ToList();
                    entity.DescQty = details.Sum(t => t.DescQty);
                    entity.DespachoQty = details.Sum(t => t.DespachoQty);
                    entity.EntradaQty = details.Sum(t => t.EntradaQty);
                    entity.TotalQty = details.Sum(t => t.Qty);
                    entity.Total = details.Sum(t => t.Total);

                    _client.Deleteable(detail).ExecuteCommand();

                    _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Stroge_SyncQty", new { Id = entity.Id });
                    //_client.Updateable(entity).ExecuteCommand();
                    result.IsSuccess = true;
                    result.Msg = "操作成功";
                    var _stocksBal = new StocksBal(_capBus);
                    result = _stocksBal.ModifyStockQty(userToken, new List<Guid>() { detail.MaterialId }).Result;

                    if (result.IsSuccess)
                        new Task(() =>
                        {
                            var matNameList = $"{detail.MaterialName}{detail.ColorName}{detail.SizeName}{detail.Specs}{detail.VatNo}:{detail.Qty}{detail.UnitName}";
                            OperateLog(new OperateLogModel
                            {
                                TenantId = userToken.TenantId,
                                BillId = entity.Id,
                                Creator = userToken.UserId,
                                CreatorName = userToken.UserName,
                                BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                                BillNo = entity.BillNo,
                                RelationType = "",
                                RelationBillNo = "",
                                CreateTime = DateTime.Now,
                                CommandName = $"删除{(entity.BillType == 40 ? "出库" : "入库")}单明细",
                                TableName = entity.GetType().Name,
                                Remark = $"删除{(entity.BillType == 40 ? "出库" : "入库")}单明细",
                                OldValue = JsonSerializerHelper.Encode(detail),
                            });
                        }).Start();
                }
                else
                {
                    result.IsSuccess = false;
                    result.Msg = "无此单据";
                }
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Msg = ex.Message;
                ex.ToExceptionless().Submit();
            }
            return result;
        }
        /// <summary>
        /// 获取单据
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public MSStrogeModel GetById(UserToken userToken, Guid Id, string billNo = "")
        {
            var result = new MSStrogeModel();

            result = _client.Queryable<MS_Stroge, BAS_Company, HR_Dept, HR_Dept, HR_Member, HR_Dept>((s, c, d, e, m, h) => new object[]
             {
                JoinType.Left, s.CompanyId == c.CompanyId,
                JoinType.Left, s.DepotId == d.DeptID,
                JoinType.Left, s.ToDepotId == e.DeptID,
                JoinType.Left, s.HandmanId == m.Id,
                JoinType.Left, s.CompanyId == h.DeptID
             })
                .Where((s, c, d, e, m, h) => s.TenantId == userToken.TenantId)
                .WhereIF(Id != Guid.Empty, (s, c, d, e, m, h) => s.Id == Id)
                .WhereIF(!string.IsNullOrEmpty(billNo), (s, c, d, e, m, h) => s.BillNo == billNo)
                .Select((s, c, d, e, m, h) => new MSStrogeModel
                {
                    BillDate = s.BillDate,
                    BillNo = s.BillNo,
                    Status = s.Status,
                    DepotStatus = s.DepotStatus,
                    BillType = s.BillType,
                    PrintNum = s.PrintNum,
                    InnerBillNo = s.InnerBillNo,
                    DespachoQty = s.DespachoQty,
                    EntradaQty = s.EntradaQty,
                    ShipType = s.ShipType,
                    SourceBillNo = s.SourceBillNo,
                    CompanyId = s.CompanyId,
                    DescQty = s.DescQty,
                    OrgTotal = s.OrgTotal,
                    Remark = s.Remark,
                    Total = s.Total,
                    TotalQty = s.TotalQty,
                    CompanyBillNo = s.CompanyBillNo,
                    DepotId = s.DepotId,
                    Discount = s.Discount,
                    Handman = m.MemberName,
                    HandmanId = s.HandmanId,
                    Id = s.Id,
                    IsAutoBuild = s.IsAutoBuild,
                    ToDepotId = s.ToDepotId,
                    WPNames = s.WPNames,
                    CompanyName = SqlFunc.IsNull(c.CompanyName, h.DeptName),
                    DepotName = d.DeptName,
                    ToDepotName = e.DeptName,
                    ClassId = s.ClassId,
                    SourceBillType = s.SourceBillType,
                    CreateTime = s.CreateTime,
                    RelatedBillNo = s.RelatedBillNo,
                })
                .First();

            if (result == null)
                return result;

            result.StrogeDetails = new List<MSStrogeDetailModel>();

            //switch (result.SourceBillType)
            //{
            //    case 13:
            //    case 14:
            //    case 23:
            //    case 24:
            //    case 33:
            //    case 34:
            //    case 43:
            //    case 44:
            //    case 53:
            //    case 54:
            //        result.DespachoQty = -result.DespachoQty;
            //        result.EntradaQty = -result.EntradaQty;
            //        break;
            //    default:
            //        break;
            //}
            var details = _client.Queryable<MS_StrogeDetail, BAS_Material>((t, a) => new object[] { JoinType.Left, t.MaterialId == a.MaterialId })
                .Where(t => t.TenantId == userToken.TenantId && t.StrogeId == result.Id)
                .Select((t, a) => new MSStrogeDetailModel
                {
                    SizeName = t.SizeName,
                    Color = a.ColorName,
                    SourceBillNo = t.SourceBillNo,
                    Specs = t.Specs,
                    StrogeId = t.StrogeId,
                    ColorName = t.ColorName,
                    CompanyMaterialNo = a.CompanyMaterialNo,
                    DescQty = t.DescQty,
                    DespachoQty = t.DespachoQty,
                    Total = t.Total,
                    EntradaQty = t.EntradaQty,
                    Id = t.Id,
                    MaterialId = t.MaterialId,
                    MaterialName = a.MaterialName,
                    MaterialNo = a.MaterialNo,
                    MatName = a.MaterialName,
                    OrderId = t.OrderId,
                    PhotoUrl = a.PhotoUrl,
                    PositionNo = t.PositionNo,
                    Price = t.Price,
                    Qty = t.Qty,
                    Remark = t.Remark,
                    UnitName = t.UnitName,
                    UseProductNo = t.UseProductNo,
                    VatNo = t.VatNo,
                    Weight = t.Weight,
                })
                .OrderBy(t => new { /*t.MaterialNo, t.ColorName, */t.OrderId, /*t.Specs, t.VatNo,*/ }).ToList();

            switch (result.SourceBillType / 10)
            {
                case 1:
                    break;
                case 2:
                    break;
                case 3:
                    break;
                case 4:
                    break;
                case 5:
                    break;
                case 6:
                    break;
                case 7:
                    break;
                case 8:
                    break;
                default:
                    break;
            }


            result.StrogeDetails = details;

            result.ShipTypeName = ObjectHelper.GetEnumDescription<SaleOrderShipTypeEnum>(result.ShipType);
            result.BillTypeName = result.BillType == 40 ? "出库单" : "入库单";
            result.DepotStatusName = ObjectHelper.GetEnumDescription<SaleOrderDepotStatusEnum>(result.DepotStatus);
            result.StatusName = ObjectHelper.GetEnumDescription<SaleOrderStatusEnum>(result.Status);

            //1X:采购,2X:销售,3X:调拨，4X生产，5X委外，，1=正常入，2=正常出，3=退入，4=退出
            var billtypestr = result.SourceBillType.ToString("00");

            var bills = new string[] { "采购", "销售", "调拨", "生产", "委外", "盘点", "产品设计", "委外收货" };
            var types = new string[] { "入库", "出库", "退入", "退出", "返修", "配货" };
            var billindex = Convert.ToInt32(billtypestr[0].ToString());
            var typeindex = Convert.ToInt32(billtypestr[1].ToString());
            if (result.SourceBillType == 0)
                result.SourceBillTypeName = "手工" + (result.BillType == 41 ? "入库" : "出库");
            else
                result.SourceBillTypeName = bills[billindex - 1] + types[typeindex - 1];
            if (result.SourceBillType == 16)
                result.SourceBillTypeName = "采购返修";
            result.ClassName = result.ClassId == 0 ? "商品" : "物料";

            return result;
        }

        /// <summary>
        /// 获取单据
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public MSStrogeModel GetByShareId(Guid Id)
        {
            var result = new MSStrogeModel();

            result = _client.Queryable<MS_Stroge, BAS_Company, HR_Dept, HR_Dept, HR_Member, HR_Dept>((s, c, d, e, m, h) => new object[]
             {
                JoinType.Left, s.CompanyId == c.CompanyId,
                JoinType.Left, s.DepotId == d.DeptID,
                JoinType.Left, s.ToDepotId == e.DeptID,
                JoinType.Left, s.HandmanId == m.Id,
                JoinType.Left, s.CompanyId == h.DeptID
             })
                .Where((s, c, d, e, m, h) => s.Id == Id)
                .Select((s, c, d, e, m, h) => new MSStrogeModel
                {
                    BillDate = s.BillDate,
                    BillNo = s.BillNo,
                    Status = s.Status,
                    DepotStatus = s.DepotStatus,
                    BillType = s.BillType,
                    PrintNum = s.PrintNum,
                    InnerBillNo = s.InnerBillNo,
                    DespachoQty = s.DespachoQty,
                    EntradaQty = s.EntradaQty,
                    ShipType = s.ShipType,
                    SourceBillNo = s.SourceBillNo,
                    CompanyId = s.CompanyId,
                    DescQty = s.DescQty,
                    OrgTotal = s.OrgTotal,
                    Remark = s.Remark,
                    Total = s.Total,
                    TotalQty = s.TotalQty,
                    CompanyBillNo = s.CompanyBillNo,
                    DepotId = s.DepotId,
                    Discount = s.Discount,
                    Handman = m.MemberName,
                    HandmanId = s.HandmanId,
                    Id = s.Id,
                    IsAutoBuild = s.IsAutoBuild,
                    ToDepotId = s.ToDepotId,
                    WPNames = s.WPNames,
                    CompanyName = SqlFunc.IsNull(c.CompanyName, h.DeptName),
                    DepotName = d.DeptName,
                    ToDepotName = e.DeptName,
                    ClassId = s.ClassId,
                    SourceBillType = s.SourceBillType,
                    CreateTime = s.CreateTime,
                    RelatedBillNo = s.RelatedBillNo,
                })
                .First();

            if (result == null)
                return result;

            result.StrogeDetails = new List<MSStrogeDetailModel>();

            var details = _client.Queryable<MS_StrogeDetail, BAS_Material>((t, a) => new object[] { JoinType.Left, t.MaterialId == a.MaterialId })
                .Where(t => t.StrogeId == result.Id)
                .Select((t, a) => new MSStrogeDetailModel
                {
                    SizeName = t.SizeName,
                    Color = a.ColorName,
                    SourceBillNo = t.SourceBillNo,
                    Specs = t.Specs,
                    StrogeId = t.StrogeId,
                    ColorName = t.ColorName,
                    CompanyMaterialNo = a.CompanyMaterialNo,
                    DescQty = t.DescQty,
                    DespachoQty = t.DespachoQty,
                    Total = t.Total,
                    EntradaQty = t.EntradaQty,
                    Id = t.Id,
                    MaterialId = t.MaterialId,
                    MaterialName = a.MaterialName,
                    MaterialNo = a.MaterialNo,
                    MatName = a.MaterialName,
                    OrderId = t.OrderId,
                    PhotoUrl = a.PhotoUrl,
                    PositionNo = t.PositionNo,
                    Price = t.Price,
                    Qty = t.Qty,
                    Remark = t.Remark,
                    UnitName = t.UnitName,
                    UseProductNo = t.UseProductNo,
                    VatNo = t.VatNo,
                    Weight = t.Weight,
                })
                .OrderBy(t => new { /*t.MaterialNo, t.ColorName, */t.OrderId, /*t.Specs, t.VatNo,*/ }).ToList();
            result.StrogeDetails = details;
            result.ShipTypeName = ObjectHelper.GetEnumDescription<SaleOrderShipTypeEnum>(result.ShipType);
            result.BillTypeName = result.BillType == 40 ? "出库单" : "入库单";
            result.DepotStatusName = ObjectHelper.GetEnumDescription<SaleOrderDepotStatusEnum>(result.DepotStatus);
            result.StatusName = ObjectHelper.GetEnumDescription<SaleOrderStatusEnum>(result.Status);

            //1X:采购,2X:销售,3X:调拨，4X生产，1=正常入，2=正常出，3=退入，4=退出
            var billtypestr = result.SourceBillType.ToString("00");

            var bills = new string[] { "采购", "销售", "调拨", "生产", "委外", "盘点", "产品设计", "委外收货" };
            var types = new string[] { "入库", "出库", "退入", "退出", "自动" };
            var billindex = Convert.ToInt32(billtypestr[0].ToString());
            var typeindex = Convert.ToInt32(billtypestr[1].ToString());
            if (result.SourceBillType == 0)
                result.SourceBillTypeName = "手工" + (result.BillType == 41 ? "入库" : "出库");
            else
                result.SourceBillTypeName = bills[billindex - 1] + types[typeindex - 1];

            result.ClassName = result.ClassId == 0 ? "商品" : "物料";

            return result;
        }
        /// <summary>
        /// 获取关联单据
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public List<MSStrogeModel> GetBySourceBillNo(UserToken userToken, string sourceBillNo)
        {
            var result = new List<MSStrogeModel>();

            var list = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.SourceBillNo.Contains(sourceBillNo)).ToList();
            if (list == null || list.Count <= 0)
            {
                return new List<MSStrogeModel>();
            }
            var stocks = _client.Queryable<HR_Dept>().Where(t => t.TenantId == userToken.TenantId);
            var members = _client.Queryable<HR_Member>().Where(t => t.TenantId == userToken.TenantId);

            var idLists = list.Select(t => t.Id).ToList();

            var allDetails = _client.Queryable<MS_StrogeDetail, BAS_Material>((t, a) => new object[] { JoinType.Left, t.MaterialId == a.MaterialId })
                .Where(t => t.TenantId == userToken.TenantId && idLists.Contains(t.StrogeId))
                .Select((t, a) => new MSStrogeDetailModel
                {
                    SizeName = t.SizeName,
                    Color = a.ColorName,
                    SourceBillNo = t.SourceBillNo,
                    Specs = t.Specs,
                    StrogeId = t.StrogeId,
                    ColorName = t.ColorName,
                    CompanyMaterialNo = a.CompanyMaterialNo,
                    DescQty = t.DescQty,
                    DespachoQty = t.DespachoQty,
                    Total = t.Total,
                    EntradaQty = t.EntradaQty,
                    Id = t.Id,
                    MaterialId = t.MaterialId,
                    MaterialName = a.MaterialName,
                    MaterialNo = a.MaterialNo,
                    MatName = a.MaterialName,
                    OrderId = t.OrderId,
                    PhotoUrl = a.PhotoUrl,
                    PositionNo = t.PositionNo,
                    Price = t.Price,
                    Qty = t.Qty,
                    Remark = t.Remark,
                    UnitName = t.UnitName,
                    UseProductNo = t.UseProductNo,
                    VatNo = t.VatNo,
                    Weight = t.Weight,
                })
                .OrderBy(t => new { /*t.MaterialNo, t.ColorName, */t.OrderId, /*t.Specs, t.VatNo,*/ }).ToList();

            foreach (var item in list)
            {

                var entity = ObjectHelper.Mapper<MSStrogeModel, MS_Stroge>(item);
                entity.StrogeDetails = new List<MSStrogeDetailModel>();

                var dept = stocks.Where(t => t.DeptID == entity.DepotId);
                if (dept.Any())
                {
                    entity.DepotName = dept.First().DeptName;
                }
                var member = members.Where(t => t.Id == item.HandmanId);
                if (member.Any())
                {
                    entity.Handman = member.First().MemberName;
                }

                entity.StrogeDetails = allDetails.Where(t => t.StrogeId == item.Id).ToList();

                result.Add(entity);
            }

            return result;
        }

        public List<SelectTypeDataModel> GetStrogeCompanyList(UserToken userToken, int classId, int companyType)
        {
            var data = _client.Queryable<MS_Stroge, BAS_Company>((a, b) => new object[] { JoinType.Left, a.CompanyId == b.CompanyId })
                .Where((a, b) => a.TenantId == userToken.TenantId && a.Status > 0 && a.ClassId == classId && !SqlFunc.IsNullOrEmpty(b.CompanyName))
                .WhereIF(companyType != 0, (a, b) => b.CompanyType == companyType)
                .Select((a, b) => new SelectTypeDataModel { Type = b.CompanyType, Id = a.CompanyId, Name = b.CompanyName, }).Distinct().ToList();

            return data;
        }
        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public PageDataModel<MSStrogeModel> GetList(UserToken userToken, StrogeSearchModel model)
        {
            if (model.BillType == 40)
                _billRoleType = BillRoleTypeEnum.OutStock.ToString();
            else
                _billRoleType = BillRoleTypeEnum.InStock.ToString();

            var role = _client.Queryable<HR_Member, HR_Dept, SYS_TenantAccount, MS_BillRole, SYS_Tenant>((a, b, c, d, e) => new object[] { JoinType.Left, a.DeptId == b.DeptID, JoinType.Left, b.TenantId == c.TenantId, JoinType.Left, a.UserId == d.UserId && d.BillTable == _billRoleType, JoinType.Left, c.MasterTenantId == e.MasterTenantId, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && a.UserId == userToken.UserId && d.BillTable == _billRoleType)
                .Select((a, b, c, d, e) => new BillDeptRoleModel { MemberId = a.Id, DeptId = b.DeptID, HeadId = b.HeadId, MemberName = a.MemberName, RoleId = a.RoleId, RoleType = SqlFunc.IIF(a.Phone == e.Phone, 4, d.RoleType), UserId = a.UserId, TenantUserId = c.Creator, })
                .First();

            var deptIds = _client.Queryable<HR_Dept, HR_DeptRelation, HR_Dept, HR_Member>((a, b, c, d) => new object[] { JoinType.Left, a.DeptID == b.ParentId, JoinType.Left, b.DeptID == c.DeptID, JoinType.Left, a.DeptID == d.DeptId })
                .Where((a, b, c, d) => d.UserId == userToken.UserId && SqlFunc.IsNull(c.DeptID, Guid.Empty) != Guid.Empty).Select((a, b, c) => c.DeptID).Distinct().ToList();

            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceType = StringHelper.StrSplitInt(model.SourceBillType, ",");

            var q = _client.Queryable<MS_Stroge, BAS_Company, HR_Dept, HR_Dept, HR_Member>((s, c, d, e, m) => new object[]
             {
                JoinType.Left, s.CompanyId == c.CompanyId,
                JoinType.Left, s.DepotId == d.DeptID,
                JoinType.Left, s.ToDepotId == e.DeptID,
                JoinType.Left, s.HandmanId == m.Id,
             })
                .Where((s, c, d, e, m) => s.TenantId == userToken.TenantId && s.ClassId == model.ClassId)
                .WhereIF(model.BeginDate != DateTime.MinValue, (s, c, d, e, m) => s.BillDate >= model.BeginDate)
                .WhereIF(model.EndDate != DateTime.MinValue, (s, c, d, e, m) => s.BillDate < model.EndDate)
                .WhereIF(model.BillType > 0, (s, c, d, e, m) => s.BillType == model.BillType)
                .WhereIF(!string.IsNullOrEmpty(model.DcNo), (s, c, d, e, m) => model.DcNo == s.DcNo)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (s, c, d, e, m) => depotStatus.Contains(s.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Status), (s, c, d, e, m) => status.Contains(s.Status))
                .WhereIF(!string.IsNullOrEmpty(model.SourceBillType), (s, c, d, e, m) => sourceType.Contains(s.SourceBillType))
                .WhereIF(model.CompanyId != Guid.Empty, (s, c, d, e, m) => s.CompanyId == model.CompanyId)
                .WhereIF(model.UserId != Guid.Empty, (s, c, d, e, m) => s.Creator == model.UserId || s.HandmanId == model.UserId)
                .WhereIF(model.InDeptId != Guid.Empty, (s, c, d, e, m) => s.DepotId == model.InDeptId)
                .WhereIF(model.InDeptId == Guid.Empty, (s, c, d, e, m) => deptIds.Contains(s.DepotId))
                .WhereIF(model.IsPrintf == 0, (s, c, d, e, m) => s.PrintNum == 0)
                .WhereIF(model.IsPrintf > 0, (s, c, d, e, m) => s.PrintNum > 0)
                .WhereIF(model.IsShare == 0, (s, c, d, e, m) => s.ShareNum == 0)
                .WhereIF(model.IsShare > 0, (s, c, d, e, m) => s.ShareNum > 0)
                .WhereIF(!string.IsNullOrEmpty(model.CompanyName), (s, c, d, e, m) => c.CompanyName.Contains(model.CompanyName))
                .WhereIF(!string.IsNullOrEmpty(model.Handman), (s, c) => s.Handman == model.Handman)
                .WhereIF(!string.IsNullOrEmpty(model.BillNo), (s, c) => s.BillNo == model.BillNo)
                .WhereIF(!string.IsNullOrEmpty(model.MaterialNo), (s, c, d, e, m) =>
                    s.Id == SqlFunc.Subqueryable<MS_StrogeDetail>().Where(t => t.StrogeId == s.Id && (t.MaterialName.Contains(model.MaterialNo) || t.MaterialNo.Contains(model.MaterialNo)) /*|| t.ColorName.Contains(model.Key)) || t.SizeName.Contains(model.Key) || t.Specs.Contains(model.Key) || t.Remark.Contains(model.Key)*/).Select(t => t.StrogeId)
                )
                //.WhereIF(sourceType != null && model.IsSale && (sourceType.Contains(25) || sourceType.Contains(22) || sourceType.Contains(23)), (s, c, d, e, m) => d.HeadId == userToken.UserId || c.MemberId == userToken.MemberId)
                .WhereIF(model.IsSale, (s, c, d, e, m) => c.CompanyType == 1 && d.HeadId == userToken.UserId || c.MemberId == userToken.MemberId)
                .WhereIF(role != null && role.RoleType == (int)BillRoleEnum.Dept, (s, c, d, e, m) => s.DepotId == userToken.DeptId)
                .WhereIF(role != null && !model.IsSale && role.RoleType == (int)BillRoleEnum.User, (s, c, d, e, m) => s.Creator == userToken.UserId || s.HandmanId == userToken.MemberId)
                .WhereIF(!string.IsNullOrEmpty(model.Key), (s, c, d, e, m) =>
                    s.BillNo.Contains(model.Key) ||//订单号
                                                   //s.InnerBillNo.Contains(model.Key) ||//内部单号
                    s.Remark.Contains(model.Key) ||//备注
                                                   //s.Handman.Contains(model.Key) ||//销售员
                    s.SourceBillNo.Contains(model.Key) ||
                    //c.CompanyName.Contains(model.Key) ||
                    s.Id == SqlFunc.Subqueryable<MS_StrogeDetail>().Where(t => t.StrogeId == s.Id && (t.MaterialName.Contains(model.Key) || t.MaterialNo.Contains(model.Key))/* || t.ColorName.Contains(model.Key)) || t.SizeName.Contains(model.Key) || t.Specs.Contains(model.Key)*//* || t.Remark.Contains(model.Key)*/).Select(t => t.StrogeId)
                );

            var data = q.Clone()
                .Select((s, c, d, e, m) => new MSStrogeModel
                {
                    BillDate = s.BillDate,
                    BillNo = s.BillNo,
                    Status = s.Status,
                    DepotStatus = s.DepotStatus,
                    BillType = s.BillType,
                    PrintNum = s.PrintNum,
                    InnerBillNo = s.InnerBillNo,
                    DespachoQty = s.DespachoQty,
                    EntradaQty = s.EntradaQty,
                    ShipType = s.ShipType,
                    SourceBillNo = s.SourceBillNo,
                    CompanyId = s.CompanyId,
                    DescQty = s.DescQty,
                    OrgTotal = s.OrgTotal,
                    Remark = s.Remark,
                    Total = s.Total,
                    TotalQty = s.TotalQty,
                    CompanyBillNo = s.CompanyBillNo,
                    DepotId = s.DepotId,
                    Discount = s.Discount,
                    Handman = m.MemberName,
                    HandmanId = s.HandmanId,
                    Id = s.Id,
                    IsAutoBuild = s.IsAutoBuild,
                    ToDepotId = s.ToDepotId,
                    WPNames = s.WPNames,
                    CompanyName = c.CompanyName,
                    DepotName = d.DeptName,
                    ToDepotName = e.DeptName,
                    ClassId = s.ClassId,
                    SourceBillType = s.SourceBillType,
                    CreateTime = s.CreateTime,
                    ShareNum = s.ShareNum,
                })
                .MergeTable()
                .OrderByIF(string.IsNullOrEmpty(model.SortType), s => s.CreateTime, SqlSugar.OrderByType.Desc)
                .OrderByIF(!string.IsNullOrEmpty(model.SortType), "" + model.SortType)
                .ToPageList(model.PageIndex, model.PageSize);

            var totals = q.Clone().Select((s, c) => new { Counts = SqlFunc.AggregateCount(1), TotalPrice = SqlFunc.AggregateSum(s.Total), TotalQty = SqlFunc.AggregateSum(s.TotalQty), TotalEntradaQty = SqlFunc.AggregateSum(s.EntradaQty), TotalDescQty = SqlFunc.AggregateSum(s.DescQty), TotalDespachoQty = SqlFunc.AggregateSum(s.DespachoQty) }).First();

            var orderIds = data.Select(t => t.Id).ToArray();
            var details = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && orderIds.Contains(t.StrogeId))
                .Select<MSStrogeDetailModel>(t => new MSStrogeDetailModel
                {
                    DescQty = t.DescQty,
                    DespachoQty = t.DespachoQty,
                    EntradaQty = t.EntradaQty,
                    Qty = t.Qty,
                    SizeName = t.SizeName,
                    Specs = t.Specs,
                    StrogeId = t.StrogeId,
                    ColorName = t.ColorName,
                    Id = t.Id,
                    MaterialId = t.MaterialId,
                    MaterialName = t.MaterialName,
                    MaterialNo = t.MaterialNo,
                    OrderId = t.OrderId,
                    PhotoUrl = t.PhotoUrl,
                    Price = t.Price,
                    Remark = t.Remark,
                    Total = t.Total,
                    UnitName = t.UnitName,
                    VatNo = t.VatNo,
                    PositionNo = t.PositionNo,
                    SourceBillNo = t.SourceBillNo,
                    UseProductNo = t.UseProductNo,
                }).OrderBy(t => new { t.MaterialNo, t.ColorName, t.OrderId, t.Specs, t.VatNo, }).ToList();
            foreach (var item in data)
            {
                var temps = details.Where(t => t.StrogeId == item.Id).ToList();
                item.StrogeDetails = temps;
            }

            return new PageDataModel<MSStrogeModel>
            {
                DataList = data,
                PageIndex = model.PageIndex,
                PageSize = model.PageSize,
                Total = totals.Counts,
                TotalQty = totals.TotalQty,
                TotalPrice = totals.TotalPrice,
                TotalDescQty = totals.TotalDescQty,
                TotalDespachoQty = totals.TotalDespachoQty,
                TotalEntradaQty = totals.TotalEntradaQty,
                PageTotalPrice = data.Sum(t => t.Total),
                PageTotalQty = data.Sum(t => t.TotalQty),
            };
        }
        /// <summary>
        /// 取最后一次销售价格
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="productIds"></param>
        /// <param name="custSalesMan"></param>
        /// <returns></returns>
        public List<LastSalePriceModel> GetLastPrice(UserToken userToken, LastSalePriceQueryModel model)
        {
            //取最后一次销售记录
            var proDetails = _client.Queryable<MS_StrogeDetail, MS_Stroge>((a, b) => new object[] { JoinType.Left, a.StrogeId == b.Id })
                .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == model.CompanyId && model.ProductIds.Contains(a.MaterialId))
                //.OrderBy(a => a.CreateTime, OrderByType.Desc)
                .Select((a, b) => new { b.BillDate, MaterialId = a.MaterialId, ColorName = a.ColorName, SizeName = a.SizeName, Price = a.Price, })
                .MergeTable()
                .PartitionBy(a => new { a.MaterialId, a.ColorName, a.SizeName, a.BillDate }).Take(1)
                .Select(a => new LastSalePriceModel { MaterialId = a.MaterialId, ColorName = a.ColorName, SizeName = a.SizeName, Price = a.Price, })
                .ToList();
            return proDetails;
        }
        /// <summary>
        /// 打印计数
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public BalResult Printf(UserToken userToken, Guid Id)
        {
            var result = new BalResult();

            var entity = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id).First();
            entity.PrintNum++;

            _client.Updateable(entity).ExecuteCommand();

            result.IsSuccess = true;

            new Task(() =>
            {
                OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"{(entity.BillType == 40 ? "出库" : "入库")}单打印",
                    TableName = entity.GetType().Name,
                    Remark = $"单据打印操作",
                });
            }).Start();
            return result;
        }
        /// <summary>
        /// 打印计数
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public BalResult Share(UserToken userToken, Guid Id)
        {
            var result = new BalResult();

            var entity = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id).First();
            entity.ShareNum++;

            _client.Updateable(entity).ExecuteCommand();

            result.IsSuccess = true;

            new Task(() =>
            {
                OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"{(entity.BillType == 40 ? "出库" : "入库")}单分享",
                    TableName = entity.GetType().Name,
                    Remark = $"单据分享操作",
                });
            }).Start();
            return result;
        }

        /// <summary>
        /// 调库
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public BalResult Adjustment(UserToken userToken, Guid Id)
        {
            var result = new BalResult();
            try
            {
                var entity = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id).First();

                if (entity == null)
                {
                    result.IsSuccess = false;
                    result.Msg = "单据不存在";
                    return result;
                }
                if (entity.Status == -1)
                {
                    result.IsSuccess = false;
                    result.Msg = "单据已删除";
                    return result;
                }
                if (entity.BillType == 40 && entity.DepotStatus == 5)
                {
                    result.IsSuccess = false;
                    result.Msg = "单据已入库";
                    return result;
                }
                if (entity.BillType == 41 && entity.DepotStatus == 2)
                {
                    result.IsSuccess = false;
                    result.Msg = "单据已入库";
                    return result;
                }
                if (entity.BillType == 41)
                {
                    entity.DepotStatus = 2;
                    entity.EntradaQty = entity.TotalQty;
                    entity.DescQty = 0;
                }
                else if (entity.BillType == 40)
                {
                    entity.DepotStatus = 5;
                    entity.DespachoQty = entity.TotalQty;
                    entity.DescQty = 0;
                }

                var details = _client.Queryable<MS_StrogeDetail>().Where(t => t.TenantId == userToken.TenantId && t.StrogeId == Id).ToList();
                var matIds = details.Select(t => t.MaterialId).Distinct().ToList();
                var dept = _client.Queryable<HR_Dept>().Where(t => t.DeptID == entity.DepotId).First();
                var _stocksBal = new StocksBal(_capBus);
                if (dept.IsVerifyStock)
                {
                    var stockData = _stocksBal.GetStockQty(userToken, details.Select(t => t.MaterialId).Distinct().ToList()).Result;
                    if ((stockData.Count == 0 && details.Where(t => t.Qty < 0).Any()))
                    {
                        result.IsSuccess = false;
                        result.Msg = "产品无库存";
                        return result;
                    }
                    var nv = from s in details
                             join d in stockData.Where(t => t.DeptId == entity.DepotId).ToList() on new { s.MaterialId, s.ColorName, s.SizeName, SpecsName = s.Specs, s.VatNo } equals new { d.MaterialId, d.ColorName, d.SizeName, d.SpecsName, d.VatNo } into sdv
                             from sd in sdv.DefaultIfEmpty()
                             select new { s.MaterialId, s.MaterialNo, s.ColorName, s.SizeName, s.Specs, s.VatNo, s.DescQty, Qty = sd != null ? sd.Qty : 0 }
                            ;
                    var nvList = nv.ToList();
                    if (entity.BillType == 40)
                        nvList = nv.Where(t => t.DescQty > t.Qty).ToList();
                    else
                        nvList = nv.Where(t => t.DescQty < 0 && Math.Abs(t.DescQty) > t.Qty).ToList();
                    if (nvList.Count() > 0)
                    {
                        var msg = "";
                        foreach (var item in nvList)
                        {
                            msg += $"{item.MaterialNo}{(!string.IsNullOrEmpty(item.ColorName) ? "-" : "")}{item.ColorName}{(!string.IsNullOrEmpty(item.SizeName) ? "-" : "")}{item.SizeName}{(!string.IsNullOrEmpty(item.Specs) ? "-" : "")}{item.Specs}{(!string.IsNullOrEmpty(item.VatNo) ? "-" : "")}{item.VatNo};";
                        }
                        result.IsSuccess = false;
                        result.Msg = msg + "库存不足";

                        return result;
                    }
                }
                var barCodeTracks = new List<MS_BarCodeTrack>();
                var barCodes = _client.Queryable<MS_BarCode>().Where(a => a.TenantId == userToken.TenantId && a.BillId == entity.Id).ToList();
                var barCodeList = barCodes.Select(t => t.BarCode).ToList();

                var addDetails = new List<MS_StrogeDetail>();
                var orders = new List<SALE_Order>();
                var orderDetails = new List<SALE_OrderDetail>();
                var inOrderDetailLists = new List<SALE_OrderDetail>();
                var inLogs = new List<OperateLogModel>();
                var purchaseDetails = new List<MS_PurchaseDetail>();
                var billSourceRelateds = new List<MS_BillSourceRelated>();
                var calculations = new List<MS_ProduceCalculation>();
                var outsourcs = new List<MS_Outsourc>();
                var outsourcDetails = new List<MS_OutsourcDetail>();

                var IsStrogeToSaleOrder = false;
                if (entity.BillType == 40 && entity.SourceBillType / 10 == 2)
                {
                    var flowSet = RefitExtensions.For<ITenantSysSetAPI>(Appsettings.BaseUrl).GetTenantSet(new Data.ViewModel.SYS.Set.SysSetSearchModel() { SetTypeKey = "BillFlow", ItemKey = "FlowSet", DetailKey = "IsStrogeToSaleOrder" }, userToken.Token).Result;
                    if (flowSet != null)
                    {
                        if (flowSet?.SetTenantValue?.SetItemValue.ToLower() == "true")
                        {
                            IsStrogeToSaleOrder = true;
                        }
                    }
                }
                var tempPurDetails = new List<MS_PurchaseDetail>();
                var tempSaleDetails = new List<SALE_OrderDetail>();
                var tempOutDetails = new List<MS_OutsourcDetail>();
                var tempCalDetails = new List<MS_ProduceCalculation>();

                var sourceBillNos = new List<string>();
                if (!string.IsNullOrEmpty(entity.SourceBillNo))
                    sourceBillNos = entity.SourceBillNo.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
                switch (entity.SourceBillType)
                {
                    case 11:
                        tempPurDetails = _client.Queryable<MS_PurchaseDetail, MS_Purchase>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && b.IsDelete == false && b.BillType == 10 && b.Status > 0 && a.Qty - a.EntradaQty > 0)
                            .OrderBy((a, b) => b.CreateTime, OrderByType.Asc).ToList();
                        break;
                    case 14:
                        tempPurDetails = _client.Queryable<MS_PurchaseDetail, MS_Purchase>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && b.IsDelete == false && b.BillType == 10 && b.Status > 0 && a.EntradaQty - a.DespachoQty > 0)
                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).ToList();
                        break;
                    case 16:
                        tempPurDetails = _client.Queryable<MS_PurchaseDetail, MS_Purchase>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && b.IsDelete == false && b.BillType == 10 && b.Status > 0 && a.EntradaQty - a.DespachoQty > 0)
                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).ToList();
                        break;
                    case 22:
                    case 26:
                        tempSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0)
                                .WhereIF(sourceBillNos.Count > 0, (a, b) => sourceBillNos.Contains(b.BillNo))
                                .WhereIF(sourceBillNos.Count == 0, (a, b) => a.Qty - a.DespachoQty > 0)
                                .OrderBy((a, b) => new { b.IsDayEnd, b.CreateTime, }).ToList();
                        break;
                    case 23:
                        tempSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                               .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0)
                               .WhereIF(sourceBillNos.Count > 0, (a, b) => sourceBillNos.Contains(b.BillNo))
                                .WhereIF(sourceBillNos.Count == 0, (a, b) => a.DespachoQty - a.EntradaQty > 0)
                               .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).ToList();
                        break;
                    case 25:
                        tempSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                            .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0)
                            .WhereIF(sourceBillNos.Count > 0, (a, b) => sourceBillNos.Contains(b.BillNo))
                                .WhereIF(sourceBillNos.Count == 0, (a, b) => a.DespachoQty > 0)
                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).ToList();
                        break;
                    default:
                        break;
                }

                var sbt = entity.SourceBillType / 10;
                foreach (var item in details)
                {
                    var itemQty = 0m;
                    item.CreateTime = DateTime.Now;
                    item.Creator = userToken.UserId;

                    var barcode = barCodes.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).ToList();
                    foreach (var temp in barcode)
                    {
                        temp.CompanyId = entity.CompanyId; temp.BillDetailId = item.Id; temp.BillId = entity.Id;
                        temp.BillType = "MS_Stroge";
                        barCodeTracks.Add(new MS_BarCodeTrack() { BarCode = temp.BarCode, CommonType = 1, BillDetailId = item.Id, BillId = item.StrogeId, Status = 0, BillNo = entity.BillNo, BillType = "MS_Stroge", BundleCode = "", CompanyId = entity.CompanyId, CreateTime = DateTime.Now, Creator = userToken.UserId, Id = Guid.NewGuid(), TenantId = userToken.TenantId, MemberId = userToken.MemberId, Operation = entity.BillType, Qty = temp.Qty, DespachoQty = entity.BillType == 40 ? temp.Qty : 0, EntradaQty = entity.BillType == 41 ? temp.Qty : 0, MachineNo = entity.DcNo, PositionNo = temp.PositionNo, ProcessId = temp.ProcessId, });
                    }

                    if (entity.BillType == 40)
                    {
                        itemQty = item.Qty - item.DespachoQty;
                        item.DescQty = 0;
                        item.DespachoQty = item.Qty;
                    }
                    else if (entity.BillType == 41)
                    {
                        itemQty = item.Qty - item.EntradaQty;
                        item.DescQty = 0;
                        item.EntradaQty = item.Qty;
                    }
                    switch (sbt)
                    {
                        case 1:
                            if (entity.SourceBillType == 11)
                            {
                                tempPurDetails = tempPurDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.Specs == item.Specs).OrderBy(a => a.CreateTime).ToList();
                                foreach (var detailCol in tempPurDetails)
                                {
                                    if (itemQty == 0)
                                        break;
                                    var tempQty = detailCol.Qty - detailCol.EntradaQty > itemQty ? itemQty : detailCol.Qty - detailCol.EntradaQty;
                                    detailCol.EntradaQty += tempQty;
                                    detailCol.DescQty = detailCol.Qty - detailCol.EntradaQty;

                                    billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCol.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCol.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                    if (item.Price == 0 && detailCol.Price != 0)
                                    {
                                        item.Price = detailCol.Price;
                                        item.Tax = detailCol.Tax;
                                        item.Total = item.Price * (1 + item.Tax / 100) * item.Qty;
                                        item.Taxprice = item.Price * (item.Tax / 100) * item.Qty;
                                    }
                                    itemQty -= tempQty;
                                    purchaseDetails.Add(detailCol);
                                }
                            }
                            else if (entity.SourceBillType == 14)
                            {
                                tempPurDetails = tempPurDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.Specs == item.Specs).OrderByDescending(a => a.CreateTime).ToList();

                                foreach (var detailCol in tempPurDetails)
                                {
                                    if (itemQty == 0)
                                        break;
                                    var tempQty = detailCol.EntradaQty - detailCol.DespachoQty > itemQty ? itemQty : detailCol.EntradaQty - detailCol.DespachoQty;
                                    detailCol.DespachoQty += tempQty;

                                    billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCol.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCol.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });

                                    itemQty -= tempQty;
                                    purchaseDetails.Add(detailCol);
                                }
                            }
                            else if (entity.SourceBillType == 16)
                            {
                                tempPurDetails = tempPurDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.Specs == item.Specs).OrderByDescending(a => a.CreateTime).ToList();

                                foreach (var detailCol in tempPurDetails)
                                {
                                    if (itemQty == 0)
                                        break;
                                    var tempQty = detailCol.EntradaQty - detailCol.DespachoQty > itemQty ? itemQty : detailCol.EntradaQty - detailCol.DespachoQty;
                                    detailCol.DespachoQty += tempQty;
                                    detailCol.EntradaQty -= tempQty;
                                    detailCol.DescQty = detailCol.Qty - detailCol.EntradaQty;

                                    billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCol.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCol.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });

                                    itemQty -= tempQty;
                                    purchaseDetails.Add(detailCol);
                                }
                            }
                            break;
                        case 2:
                            if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                            {
                                tempSaleDetails = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                var orderDetailTotalQty = tempSaleDetails.Sum(t => t.Qty - t.DespachoQty);
                                if (!IsStrogeToSaleOrder && orderDetailTotalQty < itemQty)
                                {
                                    result.IsSuccess = false;
                                    result.Msg = "订单出库数已超订单未出库数，且未设置允许增加商品";
                                    return result;
                                }
                            }
                            else if (entity.SourceBillType == 25)
                            {
                                tempSaleDetails = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                var orderDetailTotalQty = tempSaleDetails.Sum(t => t.DespachoQty);
                            }
                            else
                            {
                                tempSaleDetails = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                var orderDetailTotalQty = tempSaleDetails.Sum(t => t.DespachoQty);
                            }
                            if (itemQty < 0)
                            {
                                if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                                {
                                    tempSaleDetails = tempSaleDetails.Where(a => a.DespachoQty > 0 && a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                    itemQty = Math.Abs(itemQty);
                                    foreach (var detailCol in tempSaleDetails)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > Math.Abs(detailCol.Qty - detailCol.DespachoQty) ? Math.Abs(detailCol.Qty - detailCol.DespachoQty) : itemQty;

                                        detailCol.DespachoQty -= (int)tempQty;
                                        detailCol.DescQty = detailCol.Qty - detailCol.DespachoQty;
                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCol.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCol.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = -tempQty, Wieght = 0, });
                                        orderDetails.Add(detailCol);
                                    }

                                    if (itemQty > 0)//超订单出货
                                    {
                                        result.IsSuccess = false;
                                        result.Msg = "订单出库数已超可出数";
                                        return result;
                                        var addOrderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                             .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0 && item.MaterialId == a.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.DespachoQty > 0)
                                             .OrderBy((a, b) => b.BillNo, OrderByType.Asc).ToList();

                                        foreach (var orderDetail in addOrderDetails)
                                        {
                                            if (itemQty == 0)
                                                break;
                                            var tempQty = itemQty > Math.Abs(orderDetail.Qty - orderDetail.DespachoQty) ? Math.Abs(orderDetail.Qty - orderDetail.DespachoQty) : itemQty;

                                            orderDetail.DespachoQty -= (int)tempQty;
                                            orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                            itemQty -= tempQty;
                                            billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                            orderDetails.Add(orderDetail);
                                        }
                                        if (itemQty > 0)
                                        {
                                            if (orderDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).Any())
                                            {
                                                var tempOrder = orderDetails.Where(t => t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).OrderByDescending(t => t.CreateTime).First();
                                                tempOrder.Qty += (int)itemQty;
                                                tempOrder.DespachoQty += (int)itemQty;
                                                tempOrder.Total = tempOrder.Price * (1 + tempOrder.Tax / 100) * tempOrder.Qty;
                                                tempOrder.Taxprice = tempOrder.Price * tempOrder.Tax / 100 * tempOrder.Qty;
                                            }
                                            else
                                            {
                                                SALE_OrderDetail lastOrderDetail = null;
                                                if (orderDetails.Count > 0)
                                                {
                                                    lastOrderDetail = orderDetails.OrderByDescending(t => t.CreateTime).First();
                                                }
                                                else
                                                {
                                                    result.IsSuccess = false;
                                                    result.Msg = "该客户尚未开具任何销售单，出货单无法匹配生成销售单";
                                                    return result;
                                                }
                                                var inOrderDetails = new SALE_OrderDetail()
                                                {
                                                    RecordId = Guid.NewGuid(),
                                                    KeyId = lastOrderDetail.KeyId,
                                                    SizeName = item.SizeName,
                                                    ColorName = item.ColorName,
                                                    Creator = userToken.UserId,
                                                    CreateTime = DateTime.Now,
                                                    TenantId = entity.TenantId,
                                                    CalQty = Convert.ToInt32(itemQty),
                                                    CustSalesMan = "",
                                                    CustStyleNo = "",
                                                    DealQty = Convert.ToInt32(-itemQty),
                                                    DescQty = 0,
                                                    DespachoQty = Convert.ToInt32(-itemQty),
                                                    Discount = 100,
                                                    EntradaQty = 0,
                                                    MaterialId = item.MaterialId,
                                                    MaterialName = item.MaterialName,
                                                    MaterialNo = item.MaterialNo,
                                                    PhotoUrl = item.PhotoUrl,
                                                    Price = item.Price,
                                                    Qty = Convert.ToInt32(-itemQty),
                                                    OrgPrice = item.Price,
                                                    DealTotal = itemQty * item.Price,
                                                    OrgTotal = itemQty * item.Price,
                                                    RecordType = 1,
                                                    Remark = "",
                                                    remPrice = item.Price,
                                                    Tax = item.Tax,
                                                    Taxprice = item.Tax * item.Price * itemQty / 100,
                                                    Total = itemQty * item.Price,
                                                    UnitName = item.UnitName,
                                                };
                                                inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;
                                                inOrderDetailLists.Add(inOrderDetails);
                                                inLogs.Add(new OperateLogModel
                                                {
                                                    TenantId = userToken.TenantId,
                                                    BillId = inOrderDetails.KeyId,
                                                    Creator = userToken.UserId,
                                                    CreatorName = "",
                                                    BillType = Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.销售),
                                                    BillNo = entity.BillNo,
                                                    RelationType = "",
                                                    RelationBillNo = "",
                                                    CreateTime = DateTime.Now,
                                                    CommandName = $"销售单详情",
                                                    TableName = inOrderDetails.GetType().Name,
                                                    Remark = "销售单新增销售明细",
                                                    NewValue = JsonSerializerHelper.Encode(inOrderDetails),
                                                });
                                            }
                                        }
                                    }
                                }
                                else if (entity.SourceBillType == 25)
                                {
                                    tempSaleDetails = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                    orderDetails = orderDetails.Where(t => t.Qty - t.EntradaQty > 0).OrderByDescending(t => t.CreateTime).ToList();
                                    itemQty = Math.Abs(itemQty);
                                    foreach (var orderDetail in tempSaleDetails)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.DespachoQty - orderDetail.EntradaQty ? orderDetail.DespachoQty - orderDetail.EntradaQty : itemQty;

                                        orderDetail.EntradaQty -= (int)tempQty;
                                        orderDetail.DespachoQty += (int)tempQty;
                                        orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        orderDetails.Add(orderDetail);
                                    }
                                }
                                else
                                {
                                    tempSaleDetails = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                    orderDetails = orderDetails.Where(t => t.Qty - t.EntradaQty > 0).OrderByDescending(t => t.CreateTime).ToList();
                                    itemQty = Math.Abs(itemQty);
                                    foreach (var orderDetail in tempSaleDetails)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.DespachoQty - orderDetail.EntradaQty ? orderDetail.DespachoQty - orderDetail.EntradaQty : itemQty;

                                        orderDetail.EntradaQty -= (int)tempQty;
                                        //orderDetail.DespachoQty -= (int)tempQty;
                                        //orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        orderDetails.Add(orderDetail);
                                    }
                                }
                            }
                            else if (itemQty > 0)
                            {
                                if (entity.SourceBillType == 22 || entity.SourceBillType == 26)
                                {
                                    var tempSales = tempSaleDetails.Where(a => a.DespachoQty > 0 && a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                    foreach (var orderDetail in tempSales)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                        orderDetail.DespachoQty += (int)tempQty;
                                        orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        orderDetails.Add(orderDetail);
                                    }
                                    if (itemQty > 0)
                                    {
                                        var keyIds = orderDetails.Select(t => t.KeyId).Distinct().ToList();
                                        var ordertemps = _client.Queryable<SALE_Order>().Where(a => keyIds.Contains(a.KeyId) && a.IsDayEnd == true).ToList();
                                        if (ordertemps.Count == 0)
                                        {
                                            result.IsSuccess = false;
                                            result.Msg = "非报单不允许增加商品";
                                            return result;
                                        }
                                        keyIds = ordertemps.Select(t => t.KeyId).Distinct().ToList();
                                        if (orderDetails.Where(t => keyIds.Contains(t.KeyId) && t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).Any())
                                        {
                                            var tempOrder = orderDetails.Where(t => keyIds.Contains(t.KeyId) && t.MaterialId == item.MaterialId && t.ColorName == item.ColorName && t.SizeName == item.SizeName).OrderByDescending(t => t.CreateTime).First();
                                            var oldValue = JsonSerializerHelper.Encode(tempOrder);
                                            tempOrder.Qty += (int)itemQty;
                                            tempOrder.DealQty += (int)itemQty;
                                            tempOrder.CalQty += (int)itemQty;
                                            tempOrder.DespachoQty += (int)itemQty;
                                            tempOrder.Total = tempOrder.Price * (1 + tempOrder.Tax / 100) * tempOrder.Qty;
                                            tempOrder.Taxprice = tempOrder.Price * tempOrder.Tax / 100 * tempOrder.Qty;
                                            inLogs.Add(new OperateLogModel
                                            {
                                                TenantId = userToken.TenantId,
                                                BillId = tempOrder.KeyId,
                                                Creator = userToken.UserId,
                                                CreatorName = "",
                                                BillType = Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.销售),
                                                BillNo = entity.BillNo,
                                                RelationType = "",
                                                RelationBillNo = "",
                                                CreateTime = DateTime.Now,
                                                CommandName = $"销售单详情",
                                                TableName = tempOrder.GetType().Name,
                                                Remark = "销售单明细修改(出库单回填)",
                                                OldValue = oldValue,
                                                NewValue = JsonSerializerHelper.Encode(tempOrder),
                                            });
                                        }
                                        else
                                        {
                                            SALE_OrderDetail lastOrderDetail = null;
                                            if (orderDetails.Count > 0)
                                            {
                                                lastOrderDetail = orderDetails.OrderByDescending(t => t.CreateTime).First();
                                            }
                                            else
                                            {
                                                result.IsSuccess = false;
                                                result.Msg = "该客户尚未开具任何销售单，出货单无法匹配生成销售单";
                                                return result;
                                            }
                                            var inOrderDetails = new SALE_OrderDetail()
                                            {
                                                RecordId = Guid.NewGuid(),
                                                KeyId = lastOrderDetail.KeyId,
                                                SizeName = item.SizeName,
                                                ColorName = item.ColorName,
                                                Creator = userToken.UserId,
                                                CreateTime = DateTime.Now,
                                                TenantId = entity.TenantId,
                                                CalQty = Convert.ToInt32(itemQty),
                                                CustSalesMan = "",
                                                CustStyleNo = "",
                                                DealQty = Convert.ToInt32(itemQty),
                                                DescQty = 0,
                                                DespachoQty = Convert.ToInt32(itemQty),
                                                Discount = 100,
                                                EntradaQty = 0,
                                                MaterialId = item.MaterialId,
                                                MaterialName = item.MaterialName,
                                                MaterialNo = item.MaterialNo,
                                                PhotoUrl = item.PhotoUrl,
                                                Price = item.Price,
                                                Qty = Convert.ToInt32(itemQty),
                                                OrgPrice = item.Price,
                                                DealTotal = itemQty * item.Price,
                                                OrgTotal = itemQty * item.Price,
                                                RecordType = 1,
                                                Remark = "",
                                                remPrice = item.Price,
                                                Tax = item.Tax,
                                                Taxprice = item.Tax * item.Price * itemQty / 100,
                                                Total = itemQty * item.Price,
                                                UnitName = item.UnitName,
                                            };
                                            inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;
                                            inOrderDetailLists.Add(inOrderDetails);
                                            inLogs.Add(new OperateLogModel
                                            {
                                                TenantId = userToken.TenantId,
                                                BillId = inOrderDetails.KeyId,
                                                Creator = userToken.UserId,
                                                CreatorName = "",
                                                BillType = Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.销售),
                                                BillNo = entity.BillNo,
                                                RelationType = "",
                                                RelationBillNo = "",
                                                CreateTime = DateTime.Now,
                                                CommandName = $"销售单详情",
                                                TableName = inOrderDetails.GetType().Name,
                                                Remark = "销售单新增销售明细",
                                                NewValue = JsonSerializerHelper.Encode(inOrderDetails),
                                            });
                                        }
                                    }
                                }
                                else if (entity.SourceBillType == 25)
                                {
                                    var tempSales = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();

                                    foreach (var orderDetail in tempSales)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.DespachoQty - orderDetail.EntradaQty ? orderDetail.DespachoQty - orderDetail.EntradaQty : itemQty;

                                        orderDetail.EntradaQty += (int)tempQty;
                                        orderDetail.DespachoQty -= (int)tempQty;
                                        orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;

                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        orderDetails.Add(orderDetail);
                                    }
                                    if (itemQty > 0)//超订单数发货
                                    {
                                        var addOrderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                             .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0 && item.MaterialId == a.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.DespachoQty - a.EntradaQty > 0)
                                             .OrderBy((a, b) => b.BillNo, OrderByType.Desc).ToList();

                                        foreach (var orderDetail in addOrderDetails)
                                        {
                                            if (itemQty == 0)
                                                break;
                                            var tempQty = itemQty > orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                            orderDetail.EntradaQty += (int)tempQty;
                                            orderDetail.DespachoQty -= (int)tempQty;
                                            orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                            itemQty -= tempQty;
                                            billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                            orderDetails.Add(orderDetail);
                                        }
                                    }
                                    if (0 < itemQty)
                                    {
                                        result.IsSuccess = false;
                                        result.Msg = "订单返修数已超订单数";
                                        return result;
                                    }
                                }
                                else
                                {
                                    var tempSales = tempSaleDetails.Where(a => a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName).ToList();
                                    itemQty = Math.Abs(itemQty);
                                    foreach (var orderDetail in tempSales)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > orderDetail.DespachoQty - orderDetail.EntradaQty ? orderDetail.DespachoQty - orderDetail.EntradaQty : itemQty;

                                        orderDetail.EntradaQty -= (int)tempQty;

                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        orderDetails.Add(orderDetail);
                                    }
                                    if (itemQty > 0)//超订单数发货
                                    {
                                        var addOrderDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                             .Where((a, b) => b.CompanyId == entity.CompanyId && b.IsDelete == false && b.Status > 0 && item.MaterialId == a.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.DespachoQty - a.EntradaQty > 0)
                                             .OrderBy((a, b) => b.BillNo, OrderByType.Desc).ToList();

                                        foreach (var orderDetail in addOrderDetails)
                                        {
                                            if (itemQty == 0)
                                                break;
                                            var tempQty = itemQty > orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                            orderDetail.EntradaQty -= (int)tempQty;

                                            itemQty -= tempQty;
                                            billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = orderDetail.KeyId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = orderDetail.RecordId, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                            orderDetails.Add(orderDetail);
                                        }
                                    }
                                    if (0 < itemQty)
                                    {
                                        result.IsSuccess = false;
                                        result.Msg = "订单退货数已超订单数";
                                        return result;
                                    }
                                }
                            }
                            foreach (var orderDetail in addDetails)
                            {
                                if (entity.BillType == 40)
                                {
                                    orderDetail.DespachoQty = orderDetail.Qty;
                                }
                                else if (entity.BillType == 41)
                                {
                                    orderDetail.EntradaQty = orderDetail.Qty;
                                }
                            }
                            break;
                        case 3:
                            break;
                        case 4:
                        case 5:
                            if (entity.ClassId == 1)
                            {
                                if (entity.SourceBillType == 52)
                                {
                                    tempCalDetails = _client.Queryable<MS_ProduceCalculation, MS_Outsourc>((a, b) => new object[] { JoinType.Left, a.ProduceId == b.Id })
                                        .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.Specs == item.Specs && a.ProduceQty - a.DespachoQty > 0).ToList();

                                    foreach (var detailCols in tempCalDetails)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > detailCols.ProduceQty - detailCols.DespachoQty ? detailCols.ProduceQty - detailCols.DespachoQty : itemQty;

                                        detailCols.DespachoQty -= itemQty;
                                        detailCols.DescQty = detailCols.ProduceQty - detailCols.DespachoQty;
                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCols.ProduceId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCols.Id, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        calculations.Add(detailCols);
                                    }
                                }
                                else if (entity.SourceBillType == 53)
                                {
                                    tempCalDetails = _client.Queryable<MS_ProduceCalculation, MS_Outsourc>((a, b) => new object[] { JoinType.Left, a.ProduceId == b.Id })
                                        .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.Specs == item.Specs && a.DespachoQty - a.EntradaQty > 0).ToList();

                                    foreach (var detailCols in tempCalDetails)
                                    {
                                        if (itemQty == 0)
                                            break;
                                        var tempQty = itemQty > detailCols.ProduceQty - detailCols.DespachoQty ? detailCols.ProduceQty - detailCols.DespachoQty : itemQty;

                                        detailCols.EntradaQty -= tempQty;
                                        detailCols.DespachoQty += tempQty;
                                        detailCols.DescQty = detailCols.ProduceQty - detailCols.DespachoQty;
                                        itemQty -= tempQty;
                                        billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCols.ProduceId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCols.Id, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                        calculations.Add(detailCols);
                                    }
                                }
                                var sourceBillIds = calculations.Select(t => t.ProduceId).Distinct().ToList();
                                var _Outsourcs = _client.Queryable<MS_Outsourc>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                var _OutSourcCalculations = _client.Queryable<MS_ProduceCalculation>().Where(t => t.TenantId == userToken.TenantId && sourceBillIds.Contains(t.Id)).ToList();
                                foreach (var outsourc in _Outsourcs)
                                {
                                    outsourc.Status = outsourc.Status & ~(int)OutsourcStatusEnum.Picking & ~(int)OutsourcStatusEnum.CompletePick;
                                    var pcAny = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.ProduceQty);
                                    var dqQty = _OutSourcCalculations.Where(t => t.ProduceId == item.Id).Sum(t => t.DespachoQty - t.EntradaQty);

                                    if (dqQty > 0)
                                        outsourc.Status = outsourc.Status | (int)OutsourcStatusEnum.Picking;
                                    if (pcAny == dqQty)
                                        outsourc.Status = outsourc.Status | (int)OutsourcStatusEnum.CompletePick;
                                }
                            }
                            else if (entity.ClassId == 0 && entity.SourceBillType == 51)
                            {
                                tempOutDetails = _client.Queryable<MS_OutsourcDetail, MS_Outsourc>((a, b) => new object[] { JoinType.Left, a.OutsourcId == b.Id })
                                    .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == entity.CompanyId && a.MaterialId == item.MaterialId && a.ColorName == item.ColorName && a.SizeName == item.SizeName && a.Specs == item.Specs && a.Qty - a.EntradaQty > 0).ToList();

                                foreach (var detailCols in tempOutDetails)
                                {
                                    if (itemQty == 0)
                                        break;
                                    var tempQty = itemQty > detailCols.Qty - detailCols.EntradaQty ? detailCols.Qty - detailCols.EntradaQty : itemQty;

                                    detailCols.FinishedQty += itemQty;
                                    detailCols.EntradaQty += itemQty;
                                    itemQty -= tempQty;
                                    billSourceRelateds.Add(new MS_BillSourceRelated() { BillDetailId = item.Id, SourceBillId = detailCols.OutsourcId, SourceType = entity.SourceBillType, TenantId = entity.TenantId, BillId = entity.Id, SourceBillDetailId = detailCols.Id, BillType = entity.BillType, Status = 1, Id = Guid.NewGuid(), Qty = tempQty, Wieght = 0, });
                                    outsourcDetails.Add(detailCols);
                                }
                            }
                            break;
                        case 6:
                            break;
                        case 7:
                            break;
                        case 8:
                            break;
                        default:
                            break;
                    }
                }
                entity.Status = 3;
                _client.Updateable(entity).ExecuteCommand();

                _client.Updateable(details).ExecuteCommand();
                if (addDetails.Count > 0)
                    _client.Insertable(addDetails).ExecuteCommand();
                if (orderDetails.Count > 0)
                    _client.Updateable(orderDetails).ExecuteCommand();
                if (inOrderDetailLists.Count > 0)
                    _client.Insertable(inOrderDetailLists).ExecuteCommand();
                if (inLogs.Count > 0)
                    _client.Insertable(inLogs).ExecuteCommand();
                if (purchaseDetails.Count > 0)
                    _client.Updateable(purchaseDetails).ExecuteCommand();
                if (billSourceRelateds.Count > 0)
                    _client.Insertable(billSourceRelateds).ExecuteCommand();
                if (calculations.Count > 0)
                    _client.Updateable(calculations).ExecuteCommand();
                if (outsourcs.Count > 0)
                    _client.Updateable(outsourcs).ExecuteCommand();
                if (outsourcDetails.Count > 0)
                    _client.Updateable(outsourcDetails).ExecuteCommand();

                if (orderDetails.Count > 0 || inOrderDetailLists.Count > 0)
                {
                    var billNos = _client.Queryable<MS_BillSourceRelated, SALE_Order>((a, b) => new object[] { JoinType.Left, a.SourceBillId == b.KeyId }).Where((a, b) => a.BillId == entity.Id).Select((a, b) => b.BillNo).Distinct().ToList();
                    var sourceBillNo = string.Join(",", billNos);
                    _client.Updateable<MS_Stroge>().SetColumns(t => t.SourceBillNo == sourceBillNo).Where(t => t.Id == entity.Id).ExecuteCommand();

                    var keyIds = orderDetails.Select(t => t.KeyId).ToList();
                    keyIds.AddRange(inOrderDetailLists.Select(t => t.KeyId).ToList());
                    keyIds = keyIds.Distinct().ToList();
                    foreach (var item in keyIds)
                    {
                        _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_SaleOrder_SyncQty", new { Id = item });
                    }
                }
                if (purchaseDetails.Count > 0)
                {
                    var billNos = _client.Queryable<MS_BillSourceRelated, MS_Purchase>((a, b) => new object[] { JoinType.Left, a.SourceBillId == b.KeyId }).Where((a, b) => a.BillId == entity.Id).Select((a, b) => b.BillNo).Distinct().ToList();
                    var sourceBillNo = string.Join(",", billNos);
                    _client.Updateable<MS_Stroge>().SetColumns(t => t.SourceBillNo == sourceBillNo).Where(t => t.Id == entity.Id).ExecuteCommand();

                    var keyIds = purchaseDetails.Select(t => t.KeyId).Distinct().ToList();
                    foreach (var item in keyIds)
                    {
                        _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_Purchase_SyncQty", new { Id = item });
                    }
                }

                result = _stocksBal.ModifyStockQty(userToken, details.Select(t => t.MaterialId).Distinct().ToList()).Result;
                if (barCodeTracks.Count > 0)
                {
                    _client.Updateable(barCodes).ExecuteCommand();
                    _client.Insertable(barCodeTracks).ExecuteCommand();
                    var barcodes = barCodes.Select(t => t.BarCode).ToList();
                    _client.Deleteable<MS_BarCodeScanTemp>().Where(t => t.TenantId == userToken.TenantId && barcodes.Contains(t.BarCode)).ExecuteCommand();
                }

                result.IsSuccess = true;
                result.Msg = entity.Id.ToString();

                //if (!entity.IsAutoBuild && entity.SourceBillType == 22 && !string.IsNullOrEmpty(entity.SourceBillNo))
                //{
                //    //_client.Updateable(orders).ExecuteCommand();
                //    _client.Updateable(orderDetails).ExecuteCommand();
                //    _client.Insertable(billSourceRelateds).ExecuteCommand();
                //}
                new Task(() =>
                {
                    OperateLog(new OperateLogModel
                    {
                        TenantId = userToken.TenantId,
                        BillId = entity.Id,
                        Creator = userToken.UserId,
                        CreatorName = userToken.UserName,
                        BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                        BillNo = entity.BillNo,
                        RelationType = "",
                        RelationBillNo = "",
                        CreateTime = DateTime.Now,
                        CommandName = $"{(entity.BillType == 40 ? "出库" : "入库")}单调库",
                        TableName = entity.GetType().Name,
                        Remark = $"调库操作",
                    });
                }).Start();
                //}
            }
            catch (Exception)
            {
                throw;
            }
            return result;
        }

        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public BalResult Audite(UserToken userToken, Guid Id)
        {
            var result = new BalResult();
            MS_Stroge entity = null;
            var any = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id);
            if (any.Any())
                entity = any.First();
            if (entity == null)
            {
                result.IsSuccess = true;
                result.Msg = "单据不存在！";
                return result;
            }
            if (entity.Status >= 1)
            {
                result.IsSuccess = true;
                result.Msg = "单据已通过审核流程！";
                return result;
            }
            if (entity.Status == -1)
            {
                result.IsSuccess = false;
                result.Msg = "单据已删除";
                return result;
            }

            HR_Member member = null;
            var memberany = _client.Queryable<HR_Member>().Where(t => t.UserId == userToken.UserId);
            if (memberany.Any())
                member = memberany.First();

            entity.Status = 1;
            //entity.Adjustman = member?.MemberName;
            //entity.AdjustmanId = userToken.MemberId;
            var num = _client.Updateable(entity).ExecuteCommand();
            if (num > 0)
            {
                result.IsSuccess = true;
                result.Msg = "审核成功";
            }
            new Task(() =>
            {
                OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"{(entity.BillType == 40 ? "出库" : "入库")}单审核",
                    TableName = entity.GetType().Name,
                    Remark = $"审核操作",
                });
            }).Start();
            var msgapi = RefitExtensions.For<IWeChatPrivateTemplateAPI>(Appsettings.BaseUrl);
            var newentity = GetById(userToken, entity.Id);
            msgapi.StrogeWeChatMessageCustomizeData(new MsgMSStrogeModel()
            {
                Entity = newentity,
                OperatType = 1
            }, userToken.Token);
            return result;
        }
        /// <summary>
        /// 反审核
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public BalResult UnAudite(UserToken userToken, Guid Id)
        {
            var result = new BalResult();
            MS_Stroge entity = null;
            var any = _client.Queryable<MS_Stroge>().Where(t => t.TenantId == userToken.TenantId && t.Id == Id);
            if (any.Any())
                entity = any.First();
            if (entity == null)
            {
                result.IsSuccess = true;
                result.Msg = "单据不存在！";
                return result;
            }
            if (entity.Status != 1)
            {
                result.IsSuccess = true;
                result.Msg = "单据当前审核流程无法反审核！";
                return result;
            }
            if (entity.Status == -1)
            {
                result.IsSuccess = false;
                result.Msg = "单据已删除";
                return result;
            }

            HR_Member member = null;
            var memberany = _client.Queryable<HR_Member>().Where(t => t.UserId == userToken.UserId);
            if (memberany.Any())
                member = memberany.First();

            entity.Status = 0;
            //entity.Adjustman = member?.MemberName;
            //entity.AdjustmanId = userToken.MemberId;
            var num = _client.Updateable(entity).ExecuteCommand();
            if (num > 0)
            {
                result.IsSuccess = true;
                result.Msg = "反审核成功";
            }
            new Task(() =>
            {
                OperateLog(new OperateLogModel
                {
                    TenantId = userToken.TenantId,
                    BillId = entity.Id,
                    Creator = userToken.UserId,
                    CreatorName = userToken.UserName,
                    BillType = entity.BillType == 40 ? Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.出库) : Enum.GetName(typeof(OperateLogBillTypeEnum), OperateLogBillTypeEnum.入库),
                    BillNo = entity.BillNo,
                    RelationType = "",
                    RelationBillNo = "",
                    CreateTime = DateTime.Now,
                    CommandName = $"{(entity.BillType == 40 ? "出库" : "入库")}单反审核",
                    TableName = entity.GetType().Name,
                    Remark = $"反审核操作",
                });
            }).Start();
            var msgapi = RefitExtensions.For<IWeChatPrivateTemplateAPI>(Appsettings.BaseUrl);
            var newentity = GetById(userToken, entity.Id);
            msgapi.StrogeWeChatMessageCustomizeData(new MsgMSStrogeModel()
            {
                Entity = newentity,
                OperatType = 2
            }, userToken.Token);
            return result;
        }

        /// <summary>
        /// 批量打印出库单据
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<BalResult> BatchPrint(UserToken userToken, BatchPrintCreateModel model)
        {
            var list = await _client.Queryable<MS_Stroge>().Where(t => model.BillIds.Contains(t.Id)).ToListAsync();

            var prints = new List<Ten_CloudPrintTask>();
            foreach (var item in list)
            {
                var print = new Ten_CloudPrintTask()
                {
                    BillId = item.Id,
                    BillNo = item.BillNo,
                    BillType = "MS_Stroge",
                    IsBill = true,
                    PrinterId = model.PrinterId,
                    ReportId = model.ReportId,
                    IsSupplementary = false,
                    Id = Guid.NewGuid(),
                    TenantId = userToken.TenantId,
                    CreateTime = DateTime.Now,
                    Creator = userToken.UserId,
                    ExecCount = 0,
                    IsRead = false,
                    PrintTime = DateTime.MinValue,
                };

                prints.Add(print);
            }
            var number = await _client.Insertable(prints).ExecuteCommandAsync();

            return new BalResult(number > 0, "操作成功");
        }

        /// <summary>
        /// 获取报表数据源
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="Id"></param>
        /// <param name="isPrint"></param>
        /// <returns></returns>
        public StrogeReportDataSourceModel GetReportData(UserToken userToken, Guid Id, bool isPrint = true)
        {
            if (!isPrint)
                return new ReportDataSourceBal().StrogeReportDataSourceInit();

            var result = new StrogeReportDataSourceModel();

            result.Platform = new PlatformReport() { PlatformName = "好理想平台" };
            result.Tenant = new TenantReport();

            var tenantbal = RefitExtensions.For<ITenantsAPI>(Appsettings.BaseUrl);
            var tenant = tenantbal.GetByTenantId(userToken.TenantId, userToken.Token);

            if (tenant != null)
            {
                result.Tenant = ObjectHelper.Mapper<TenantReport, TenantModel>(tenant.Result);
            }
            result.Data = new MSStrogeModel();
            var data = GetById(userToken, Id);

            if (data == null && !isPrint)
            {
                data = new MSStrogeModel();
                data.StrogeDetails = new List<MSStrogeDetailModel>();
                data.StrogeDetails.Add(new MSStrogeDetailModel());
            }
            result.StrogeDetails = data.StrogeDetails.GroupBy(t => new { t.MaterialId, t.MaterialName, t.MaterialNo, t.ColorName, t.SizeName, t.Specs, t.Tax, t.UseProductNo, t.UnitName, t.VatNo, t.Color, t.CompanyMaterialNo, t.MatName, t.PhotoUrl, t.PositionNo, t.Price, t.Remark, t.SourceBillNo, })
                .Select(t => new MSStrogeDetailModel
                {
                    MaterialId = t.Key.MaterialId,
                    MaterialName = t.Key.MaterialName,
                    MaterialNo = t.Key.MaterialNo,
                    ColorName = t.Key.ColorName,
                    SizeName = t.Key.SizeName,
                    Color = t.Key.Color,
                    CompanyMaterialNo = t.Key.CompanyMaterialNo,
                    MatName = t.Key.MatName,
                    PhotoUrl = t.Key.PhotoUrl,
                    PositionNo = t.Key.PositionNo,
                    Price = t.Key.Price,
                    Remark = t.Key.Remark,
                    SourceBillNo = t.Key.SourceBillNo,
                    Specs = t.Key.Specs,
                    Tax = t.Key.Tax,
                    VatNo = t.Key.VatNo,
                    UseProductNo = t.Key.UseProductNo,
                    UnitName = t.Key.UnitName,
                    OrderId = t.Min(a => a.OrderId),
                    DescQty = t.Sum(a => a.DescQty),
                    Qty = t.Sum(a => a.Qty),
                    DespachoQty = t.Sum(a => a.DespachoQty),
                    EntradaQty = t.Sum(a => a.EntradaQty),
                    Taxprice = t.Sum(a => a.Taxprice),
                    Weight = t.Sum(a => a.Weight),
                    Total = t.Sum(a => a.Total),
                })
                //.OrderBy(t => t.Sort)
                .ToList(); ;
            data.StrogeDetails = new List<MSStrogeDetailModel>();
            //if (data.StrogeDetails == null || data.StrogeDetails.Count <= 0)
            //{
            //    data.StrogeDetails = new List<MSStrogeDetailModel>();
            //    if (!isPrint)
            //        data.StrogeDetails.Add(new MSStrogeDetailModel());
            //}
            //foreach (var item in data.StrogeDetails)
            //{
            //    //item.PhotoUrl = ImagesHelper.ImageToBase64(Config.Appsettings.PicturePath() + item.PhotoUrl);
            //}
            result.Data = data;

            result.PublicData = new object();

            result.RelatedData = new RelatedData();

            var _companysBal = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            result.Company = _companysBal.GetById(userToken.TenantId, result.Data.CompanyId).Result;

            if (!string.IsNullOrEmpty(data.SourceBillNo))
            {
                switch (data.SourceBillType)
                {
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                        var _purchasesBal = RefitExtensions.For<IPurchasesAPI>(Appsettings.BaseUrl);
                        var purchase = _purchasesBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.Purchase = purchase;
                        if (purchase != null && purchase.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, purchase.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                        var _saleOrdersBal = RefitExtensions.For<ISaleOrdersAPI>(Appsettings.BaseUrl);
                        var order = _saleOrdersBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.SaleOrder = order;
                        if (order != null && order.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, order.CompanyId);
                            result.Company = companyData.Result;
                            if (result.Company.MemberId != Guid.Empty)
                            {
                                var membersAPI = RefitExtensions.For<IMembersAPI>(Appsettings.BaseUrl);
                                var memberData = membersAPI.GetById(userToken.TenantId, result.Company.MemberId);
                                result.SalesMan = memberData.Result;
                            }
                        }
                        break;
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                        var _stockTransferBal = new StockTransferBal(_capBus);
                        var transfer = _stockTransferBal.GetById(userToken, Guid.Empty, data.SourceBillNo);
                        result.Transfer = transfer;
                        break;
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                        var _produceBal = RefitExtensions.For<IProduceAPI>(Appsettings.BaseUrl);
                        var produce = _produceBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.Produce = produce;
                        if (produce != null && produce.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, produce.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                        var _outsourcBal = RefitExtensions.For<IOutsourcAPI>(Appsettings.BaseUrl);
                        var outsourc = _outsourcBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.Outsourc = outsourc;
                        if (outsourc != null && outsourc.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, outsourc.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    default:
                        break;
                }
            }
            result.CrossSizeTitle = new List<CrossSizeModel>();
            result.CrossSizeData = new List<CrossSizeDataModel>();
            var sizeNames = result.StrogeDetails.Select(t => t.SizeName).Distinct().ToList();
            result.CrossSizeTitle = new ReportDataSourceBal().GetCrossSizeTitle(userToken, sizeNames);

            var mats = result.StrogeDetails.GroupBy(t => new { t.MaterialId, t.MaterialName, t.MaterialNo, t.ColorName })
                .Select(t => new { t.Key.MaterialId, t.Key.MaterialName, t.Key.MaterialNo, t.Key.ColorName, Sort = t.Min(a => a.OrderId), })
                .OrderBy(t => t.Sort)
                .ToList();

            foreach (var mat in mats)
            {
                var details = result.StrogeDetails.Where(t => t.MaterialId == mat.MaterialId && t.ColorName == mat.ColorName).ToList();
                var sizedata = new CrossSizeDataModel() { ColorName = mat.ColorName, MaterialId = mat.MaterialId, MaterialName = mat.MaterialName };

                System.Reflection.PropertyInfo[] sizedataItemProperties = sizedata.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);

                foreach (var item in details)
                {
                    var size = item.SizeName;
                    if (!string.IsNullOrEmpty(size))
                    {
                        var attname = ObjectHelper.GetAttributeName<CrossSizeModel>(result.CrossSizeTitle, size);
                        if (string.IsNullOrEmpty(attname))
                            continue;
                        var cfg = sizedataItemProperties.Where(t => t.Name == attname).First();
                        cfg.SetValue(sizedata, item.Qty, null);
                    }
                    //sizedata.PhotoUrl = ImagesHelper.ImageToBase64(Config.Appsettings.PicturePath() + item.PhotoUrl);
                    sizedata.Price = item.Price;
                    sizedata.Total += item.Price * item.Qty;
                    sizedata.Tax = 0;
                    sizedata.Taxprice += 0;
                    sizedata.UnitName = item.UnitName;
                    sizedata.CustSalesMan = "";
                    sizedata.CustStyleNo = "";
                    sizedata.Discount = 0;
                    sizedata.DiscountTotal += 0;
                    sizedata.MaterialNo = item.MaterialNo;
                    sizedata.Remark = item.Remark;
                }
                result.CrossSizeData.Add(sizedata);
            }
            var memberBal = RefitExtensions.For<IMembersAPI>(Appsettings.BaseUrl);
            result.Creator = memberBal.GetByUserId(data.HandmanId, userToken.Token).Result;
            var deptbal = RefitExtensions.For<IDeptsAPI>(Appsettings.BaseUrl);
            if (result.Data.DepotId != Guid.Empty)
                result.Dept = deptbal.GetById(userToken.TenantId, result.Data.DepotId).Result;

            if (result.Data.ToDepotId != Guid.Empty)
                result.ToDept = deptbal.GetById(userToken.TenantId, result.Data.ToDepotId).Result;

            return result;
        }
        public ReportDataSourceBaseModel GetSmartDistributionReportData(UserToken userToken, string FlowNo, bool isPrint = true)
        {
            if (!isPrint)
                return new ReportDataSourceBal().StrogeReportDataSourceInit();

            var result = new StrogeReportDataSourceModel();

            result.Platform = new PlatformReport() { PlatformName = "好理想平台" };
            result.Tenant = new TenantReport();

            var tenantbal = RefitExtensions.For<ITenantsAPI>(Appsettings.BaseUrl);
            var tenant = tenantbal.GetByTenantId(userToken.TenantId, userToken.Token);

            if (tenant != null)
            {
                result.Tenant = ObjectHelper.Mapper<TenantReport, TenantModel>(tenant.Result);
            }
            result.Data = new MSStrogeModel();

            var log = RefitExtensions.For<IOperateLogAPI>(Appsettings.BaseUrl).GetSmartBillLogByFlowNo(FlowNo, userToken.Token).Result.data;
            MSStrogeModel data = null;
            foreach (var item in log.Details)
            {
                var temp = GetById(userToken, item.BillId);
                if (data == null)
                {
                    data = temp;
                }
                else
                {
                    data.StrogeDetails.AddRange(temp.StrogeDetails);
                }
            }

            if (data == null && !isPrint)
            {
                data = new MSStrogeModel();
                data.StrogeDetails = new List<MSStrogeDetailModel>();
                data.StrogeDetails.Add(new MSStrogeDetailModel());
            }

            if (data.StrogeDetails == null || data.StrogeDetails.Count <= 0)
            {
                data.StrogeDetails = new List<MSStrogeDetailModel>();
                if (!isPrint)
                    data.StrogeDetails.Add(new MSStrogeDetailModel());
            }
            foreach (var item in data.StrogeDetails)
            {
                //item.PhotoUrl = ImagesHelper.ImageToBase64(Config.Appsettings.PicturePath() + item.PhotoUrl);
            }
            result.Data = data;

            result.PublicData = new object();

            result.RelatedData = new RelatedData();

            var _companysBal = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            if (!string.IsNullOrEmpty(data.SourceBillNo))
            {
                switch (data.SourceBillType)
                {
                    case 11:
                    case 12:
                    case 13:
                    case 14:
                        var _saleOrdersBal = RefitExtensions.For<ISaleOrdersAPI>(Appsettings.BaseUrl);
                        var order = _saleOrdersBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.SaleOrder = order;
                        result.SaleOrder = order;
                        if (order != null && order.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, order.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    case 21:
                    case 22:
                    case 23:
                    case 24:
                        var _purchasesBal = RefitExtensions.For<IPurchasesAPI>(Appsettings.BaseUrl);
                        var purchase = _purchasesBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.Purchase = purchase;
                        if (purchase != null && purchase.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, purchase.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    case 31:
                    case 32:
                    case 33:
                    case 34:
                        var _stockTransferBal = new StockTransferBal(_capBus);
                        var transfer = _stockTransferBal.GetById(userToken, Guid.Empty, data.SourceBillNo);
                        result.Transfer = transfer;
                        break;
                    case 41:
                    case 42:
                    case 43:
                    case 44:
                        var _produceBal = RefitExtensions.For<IProduceAPI>(Appsettings.BaseUrl);
                        var produce = _produceBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.Produce = produce;
                        if (produce != null && produce.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, produce.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    case 51:
                    case 52:
                    case 53:
                    case 54:
                        var _outsourcBal = RefitExtensions.For<IOutsourcAPI>(Appsettings.BaseUrl);
                        var outsourc = _outsourcBal.GetByNo(data.SourceBillNo, userToken.Token).Result.data;
                        result.Outsourc = outsourc;
                        if (outsourc != null && outsourc.CompanyId != Guid.Empty)
                        {
                            var companyData = _companysBal.GetById(userToken.TenantId, outsourc.CompanyId);
                            result.Company = companyData.Result;
                        }
                        break;
                    default:
                        break;
                }
            }
            result.CrossSizeTitle = new List<CrossSizeModel>();
            result.CrossSizeData = new List<CrossSizeDataModel>();
            var sizeNames = data.StrogeDetails.Select(t => t.SizeName).Distinct().ToList();
            result.CrossSizeTitle = new ReportDataSourceBal().GetCrossSizeTitle(userToken, sizeNames);

            var mats = data.StrogeDetails.GroupBy(t => new { t.MaterialId, t.MaterialName, t.MaterialNo, t.ColorName })
                .Select(t => new { t.Key.MaterialId, t.Key.MaterialName, t.Key.MaterialNo, t.Key.ColorName })
                .Distinct().ToList();

            foreach (var mat in mats)
            {
                var details = data.StrogeDetails.Where(t => t.MaterialId == mat.MaterialId && t.ColorName == mat.ColorName).ToList();
                var sizedata = new CrossSizeDataModel() { ColorName = mat.ColorName, MaterialId = mat.MaterialId, MaterialName = mat.MaterialName };

                System.Reflection.PropertyInfo[] sizedataItemProperties = sizedata.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);

                foreach (var item in details)
                {
                    var size = item.SizeName;
                    if (!string.IsNullOrEmpty(size))
                    {
                        var attname = ObjectHelper.GetAttributeName<CrossSizeModel>(result.CrossSizeTitle, size);
                        if (string.IsNullOrEmpty(attname))
                            continue;
                        var cfg = sizedataItemProperties.Where(t => t.Name == attname).First();
                        cfg.SetValue(sizedata, item.Qty, null);
                    }
                    //sizedata.PhotoUrl = ImagesHelper.ImageToBase64(Config.Appsettings.PicturePath() + item.PhotoUrl);
                    sizedata.Price = item.Price;
                    sizedata.Total += item.Price * item.Qty;
                    sizedata.Tax = 0;
                    sizedata.Taxprice += 0;
                    sizedata.UnitName = item.UnitName;
                    sizedata.CustSalesMan = "";
                    sizedata.CustStyleNo = "";
                    sizedata.Discount = 0;
                    sizedata.DiscountTotal += 0;
                    sizedata.MaterialNo = item.MaterialNo;
                    sizedata.Remark = item.Remark;
                }
                result.CrossSizeData.Add(sizedata);
            }
            var memberBal = RefitExtensions.For<IMembersAPI>(Appsettings.BaseUrl);
            result.Creator = memberBal.GetByUserId(data.HandmanId, userToken.Token).Result;
            var deptbal = RefitExtensions.For<IDeptsAPI>(Appsettings.BaseUrl);
            if (result.Data.DepotId != Guid.Empty)
                result.Dept = deptbal.GetById(userToken.TenantId, result.Data.DepotId).Result;

            if (result.Data.ToDepotId != Guid.Empty)
                result.ToDept = deptbal.GetById(userToken.TenantId, result.Data.ToDepotId).Result;

            return result;
        }

        /// <summary>
        /// 订单出货问题
        /// </summary>
        /// <param name="tenantId"></param>
        /// <returns></returns>
        public async Task<BalResult> DecomposeStroge(int tenantId)
        {
            //var tenantId = 3055;

            var allStroges = await _client.Queryable<MS_Stroge>().Where(t => t.TenantId == tenantId && t.SourceBillType / 10 == 2 && t.Status > 0).OrderBy(t => t.CreateTime).ToListAsync();
            var allStrogeDetails = await _client.Queryable<MS_StrogeDetail, MS_Stroge>((a, b) => new object[] { JoinType.Left, a.StrogeId == b.Id }).Where((a, b) => a.TenantId == tenantId && b.SourceBillType / 10 == 2 && b.Status > 0).ToListAsync();
            var allRelateds = await _client.Queryable<MS_BillSourceRelated>().Where(t => t.TenantId == tenantId).ToListAsync();
            //await _client.Updateable<SALE_OrderDetail>().SetColumns(t => t.DescQty == t.Qty).SetColumns(t => t.DespachoQty == 0).SetColumns(t => t.EntradaQty == 0).Where(t => t.TenantId == tenantId).ExecuteCommandAsync();
            var speed = 0;
            foreach (var item in allStroges)
            {
                var relatedIns = new List<MS_BillSourceRelated>();
                var relatedDel = new List<MS_BillSourceRelated>();
                var orderDetails = new List<SALE_OrderDetail>();
                var allSaleDetails = new List<SALE_OrderDetail>();
                var supSaleDetails = new List<SALE_OrderDetail>();
                var insSaleDetails = new List<SALE_OrderDetail>();
                var strogeDetails = allStrogeDetails.Where(t => t.StrogeId == item.Id).ToList();
                var matIds = strogeDetails.Select(t => t.MaterialId).Distinct().ToList();
                var billNos = new List<string>();
                if (!string.IsNullOrEmpty(item.SourceBillNo))
                {
                    billNos = item.SourceBillNo.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
                }
                if (item.BillType == 40)
                {
                    allSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                               .Where((a, b) => b.CompanyId == item.CompanyId && matIds.Contains(a.MaterialId) && b.IsDelete == false && b.Status > 0 && b.BillType != 3 && a.Qty - a.DespachoQty != 0)
                               .WhereIF(billNos.Count > 0, (a, b) => billNos.Contains(b.BillNo))
                               .OrderBy((a, b) => a.CreateTime).ToList();

                    supSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                               .Where((a, b) => b.CompanyId == item.CompanyId && matIds.Contains(a.MaterialId) && b.IsDelete == false && b.Status > 0 && b.BillType != 3 && a.Qty - a.DespachoQty != 0)
                               .OrderBy((a, b) => a.CreateTime).ToList();
                }
                else
                {
                    allSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                               .Where((a, b) => b.CompanyId == item.CompanyId && matIds.Contains(a.MaterialId) && b.IsDelete == false && b.Status > 0 && b.BillType == 3 && a.Qty - a.EntradaQty != 0)
                               .WhereIF(billNos.Count > 0, (a, b) => billNos.Contains(b.BillNo))
                               .OrderBy((a, b) => a.CreateTime).ToList();
                    supSaleDetails = _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                               .Where((a, b) => b.CompanyId == item.CompanyId && matIds.Contains(a.MaterialId) && b.IsDelete == false && b.Status > 0 && b.BillType != 3 && a.DespachoQty - a.EntradaQty != 0)
                               .WhereIF(billNos.Count > 0, (a, b) => billNos.Contains(b.BillNo))
                               .OrderBy((a, b) => a.CreateTime).ToList();
                }
                foreach (var detail in strogeDetails)
                {
                    var oldRelated = allRelateds.Where(t => t.BillDetailId == detail.Id).ToList();
                    relatedDel.AddRange(oldRelated);
                    if (item.BillType == 40)
                    {
                        if (detail.Qty > 0)
                        {
                            var itemQty = detail.Qty;
                            var orderDetailTemps = allSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).ToList();

                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty > orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                orderDetail.DespachoQty += (int)tempQty;
                                orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;

                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = item.TenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            orderDetailTemps = supSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).ToList();

                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty > orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                orderDetail.DespachoQty += (int)tempQty;
                                orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;

                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = item.TenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            if (itemQty > 0)
                            {
                                if (orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).Any())
                                {
                                    var inOrderDetails = orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).OrderByDescending(t => t.CreateTime).First();
                                    inOrderDetails.DespachoQty += (int)itemQty;
                                    if (inOrderDetails.Qty < inOrderDetails.DespachoQty)
                                        inOrderDetails.Qty = inOrderDetails.DespachoQty;
                                    inOrderDetails.DescQty = inOrderDetails.Qty - inOrderDetails.DespachoQty;

                                    var reltemp = relatedIns.Where(t => t.SourceBillDetailId == inOrderDetails.RecordId).FirstOrDefault();
                                    reltemp.Qty += itemQty;
                                }
                                else
                                {
                                    var intemp = new SALE_OrderDetail();
                                    if (allSaleDetails.Count > 0)
                                        intemp = allSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else if (supSaleDetails.Count > 0)
                                        intemp = supSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else
                                        intemp = await _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                            .Where((a, b) => b.CompanyId == item.CompanyId)
                                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).FirstAsync();

                                    var inOrderDetails = new SALE_OrderDetail()
                                    {
                                        Discount = 100,
                                        CustSalesMan = "",
                                        CustStyleNo = "",
                                        CreateTime = DateTime.Now,
                                        Creator = item.Creator,
                                        KeyId = intemp.KeyId,
                                        PhotoUrl = detail.PhotoUrl,
                                        TenantId = item.TenantId,
                                        UnitName = "",
                                        CalQty = 0,
                                        RecordId = Guid.NewGuid(),
                                        MaterialId = detail.MaterialId,
                                        ColorName = detail.ColorName,
                                        SizeName = detail.SizeName,
                                        Price = detail.Price,
                                        DealQty = (int)itemQty,
                                        MaterialName = detail.MaterialName,
                                        MaterialNo = detail.MaterialNo,
                                        OrgPrice = detail.Price,
                                        RecordType = 1,
                                        Remark = "出库单自动补数",
                                        remPrice = detail.Price,
                                        Tax = detail.Tax,
                                        Qty = (int)itemQty,
                                        DescQty = 0,
                                        DespachoQty = (int)itemQty,
                                        EntradaQty = 0,
                                    };
                                    inOrderDetails.Total = inOrderDetails.Price * inOrderDetails.Qty * (1 + inOrderDetails.Tax / 100);
                                    inOrderDetails.DealTotal = inOrderDetails.Total;
                                    inOrderDetails.OrgTotal = inOrderDetails.Total;
                                    inOrderDetails.Taxprice = inOrderDetails.Price * inOrderDetails.Qty * (inOrderDetails.Tax / 100);
                                    inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;

                                    var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = item.Id, BillDetailId = detail.Id, BillType = item.BillType, SourceType = item.SourceBillType, Status = 1, TenantId = item.TenantId, Qty = itemQty, Wieght = 0, };
                                    insSaleDetails.Add(inOrderDetails);
                                    relatedIns.Add(inRelated);
                                }
                            }
                        }
                        else
                        {
                            var itemQty = detail.Qty;
                            var orderDetailTemps = allSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).ToList();

                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty < orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                orderDetail.DespachoQty += (int)tempQty;
                                orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;

                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = tenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            orderDetailTemps = supSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).ToList();

                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty < orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                orderDetail.DespachoQty += (int)tempQty;
                                orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;

                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = tenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            if (itemQty < 0)
                            {
                                if (orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).Any())
                                {
                                    var inOrderDetails = orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).OrderByDescending(t => t.CreateTime).First();
                                    inOrderDetails.DespachoQty += (int)itemQty;
                                    if (inOrderDetails.Qty < inOrderDetails.DespachoQty)
                                        inOrderDetails.Qty = inOrderDetails.DespachoQty;
                                    inOrderDetails.DescQty = inOrderDetails.Qty - inOrderDetails.DespachoQty;

                                    var reltemp = relatedIns.Where(t => t.SourceBillDetailId == inOrderDetails.RecordId).FirstOrDefault();
                                    reltemp.Qty += itemQty;
                                }
                                else
                                {
                                    var intemp = new SALE_OrderDetail();
                                    if (allSaleDetails.Count > 0)
                                        intemp = allSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else if (supSaleDetails.Count > 0)
                                        intemp = supSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else
                                        intemp = await _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                            .Where((a, b) => b.CompanyId == item.CompanyId)
                                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).FirstAsync();

                                    var inOrderDetails = new SALE_OrderDetail()
                                    {
                                        Discount = 100,
                                        CustSalesMan = "",
                                        CustStyleNo = "",
                                        CreateTime = DateTime.Now,
                                        Creator = item.Creator,
                                        KeyId = intemp.KeyId,
                                        PhotoUrl = detail.PhotoUrl,
                                        TenantId = item.TenantId,
                                        UnitName = "",
                                        CalQty = 0,
                                        RecordId = Guid.NewGuid(),
                                        MaterialId = detail.MaterialId,
                                        ColorName = detail.ColorName,
                                        SizeName = detail.SizeName,
                                        Price = detail.Price,
                                        DealQty = (int)itemQty,
                                        MaterialName = detail.MaterialName,
                                        MaterialNo = detail.MaterialNo,
                                        OrgPrice = detail.Price,
                                        RecordType = 1,
                                        Remark = "出库单自动补数",
                                        remPrice = detail.Price,
                                        Tax = detail.Tax,
                                        Qty = (int)itemQty,
                                        DescQty = 0,
                                        DespachoQty = (int)itemQty,
                                        EntradaQty = 0,
                                    };
                                    inOrderDetails.Total = inOrderDetails.Price * inOrderDetails.Qty * (1 + inOrderDetails.Tax / 100);
                                    inOrderDetails.DealTotal = inOrderDetails.Total;
                                    inOrderDetails.OrgTotal = inOrderDetails.Total;
                                    inOrderDetails.Taxprice = inOrderDetails.Price * inOrderDetails.Qty * (inOrderDetails.Tax / 100);
                                    inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;

                                    var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = item.Id, BillDetailId = detail.Id, BillType = item.BillType, SourceType = item.SourceBillType, Status = 1, TenantId = item.TenantId, Qty = itemQty, Wieght = 0, };
                                    insSaleDetails.Add(inOrderDetails);
                                    relatedIns.Add(inRelated);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (detail.Qty > 0)
                        {
                            var itemQty = detail.Qty;
                            var orderDetailTemps = allSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).ToList();

                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty > orderDetail.DespachoQty - orderDetail.EntradaQty ? orderDetail.DespachoQty - orderDetail.EntradaQty : itemQty;

                                orderDetail.EntradaQty += (int)tempQty;
                                if (item.SourceBillType == 26)
                                {
                                    orderDetail.DespachoQty -= (int)tempQty;
                                    orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                }
                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = item.TenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            orderDetailTemps = supSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).ToList();
                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty > orderDetail.DespachoQty - orderDetail.EntradaQty ? orderDetail.DespachoQty - orderDetail.EntradaQty : itemQty;

                                orderDetail.EntradaQty += (int)tempQty;
                                if (item.SourceBillType == 26)
                                {
                                    orderDetail.DespachoQty -= (int)tempQty;
                                    orderDetail.DescQty = orderDetail.Qty - orderDetail.DespachoQty;
                                }
                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = item.TenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            if (itemQty > 0)
                            {
                                if (orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).Any())
                                {
                                    var inOrderDetails = orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty > 0).OrderByDescending(t => t.CreateTime).First();
                                    inOrderDetails.DespachoQty += (int)itemQty;
                                    if (inOrderDetails.Qty < inOrderDetails.DespachoQty)
                                        inOrderDetails.Qty = inOrderDetails.DespachoQty;
                                    inOrderDetails.DescQty = inOrderDetails.Qty - inOrderDetails.DespachoQty;

                                    var reltemp = relatedIns.Where(t => t.SourceBillDetailId == inOrderDetails.RecordId).FirstOrDefault();
                                    reltemp.Qty += itemQty;
                                }
                                else
                                {
                                    var intemp = new SALE_OrderDetail();
                                    if (allSaleDetails.Count > 0)
                                        intemp = allSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else if (supSaleDetails.Count > 0)
                                        intemp = supSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else
                                        intemp = await _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                            .Where((a, b) => b.CompanyId == item.CompanyId)
                                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).FirstAsync();

                                    var inOrderDetails = new SALE_OrderDetail()
                                    {
                                        Discount = 100,
                                        CustSalesMan = "",
                                        CustStyleNo = "",
                                        CreateTime = DateTime.Now,
                                        Creator = item.Creator,
                                        KeyId = intemp.KeyId,
                                        PhotoUrl = detail.PhotoUrl,
                                        TenantId = item.TenantId,
                                        UnitName = "",
                                        CalQty = 0,
                                        RecordId = Guid.NewGuid(),
                                        MaterialId = detail.MaterialId,
                                        ColorName = detail.ColorName,
                                        SizeName = detail.SizeName,
                                        Price = detail.Price,
                                        DealQty = (int)itemQty,
                                        MaterialName = detail.MaterialName,
                                        MaterialNo = detail.MaterialNo,
                                        OrgPrice = detail.Price,
                                        RecordType = 1,
                                        Remark = "入库单自动补数",
                                        remPrice = detail.Price,
                                        Tax = detail.Tax,
                                        Qty = (int)itemQty,
                                        DescQty = 0,
                                        EntradaQty = (int)itemQty,
                                        DespachoQty = 0,
                                    };
                                    inOrderDetails.Total = inOrderDetails.Price * inOrderDetails.Qty * (1 + inOrderDetails.Tax / 100);
                                    inOrderDetails.DealTotal = inOrderDetails.Total;
                                    inOrderDetails.OrgTotal = inOrderDetails.Total;
                                    inOrderDetails.Taxprice = inOrderDetails.Price * inOrderDetails.Qty * (inOrderDetails.Tax / 100);
                                    inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;

                                    var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = item.Id, BillDetailId = detail.Id, BillType = item.BillType, SourceType = item.SourceBillType, Status = 1, TenantId = item.TenantId, Qty = itemQty, Wieght = 0, };
                                    insSaleDetails.Add(inOrderDetails);
                                    relatedIns.Add(inRelated);
                                }
                            }
                        }
                        else
                        {
                            var orderDetailTemps = allSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).ToList();
                            var itemQty = detail.Qty;
                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty < orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                orderDetail.EntradaQty += (int)tempQty;

                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = tenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            orderDetailTemps = supSaleDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).ToList();

                            foreach (var orderDetail in orderDetailTemps)
                            {
                                if (itemQty == 0)
                                    break;
                                var tempQty = itemQty < orderDetail.Qty - orderDetail.DespachoQty ? orderDetail.Qty - orderDetail.DespachoQty : itemQty;

                                orderDetail.EntradaQty += (int)tempQty;

                                itemQty -= tempQty;
                                var inRelated = new MS_BillSourceRelated()
                                {
                                    Id = Guid.NewGuid(),
                                    TenantId = tenantId,
                                    BillId = item.Id,
                                    BillDetailId = detail.Id,
                                    SourceBillId = orderDetail.KeyId,
                                    SourceBillDetailId = orderDetail.RecordId,
                                    SourceType = item.SourceBillType,
                                    Status = 1,
                                    BillType = item.BillType,
                                    Qty = tempQty,
                                    Wieght = 0,
                                };
                                relatedIns.Add(inRelated);
                                orderDetails.Add(orderDetail);
                            }
                            if (itemQty < 0)
                            {
                                if (orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).Any())
                                {
                                    var inOrderDetails = orderDetails.Where(t => t.MaterialId == detail.MaterialId && t.ColorName == detail.ColorName && t.SizeName == detail.SizeName && t.Qty < 0).OrderByDescending(t => t.CreateTime).First();
                                    inOrderDetails.EntradaQty += (int)itemQty;

                                    var reltemp = relatedIns.Where(t => t.SourceBillDetailId == inOrderDetails.RecordId).FirstOrDefault();
                                    reltemp.Qty += itemQty;
                                }
                                else
                                {
                                    var intemp = new SALE_OrderDetail();
                                    if (allSaleDetails.Count > 0)
                                        intemp = allSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else if (supSaleDetails.Count > 0)
                                        intemp = supSaleDetails.OrderByDescending(t => t.CreateTime).First();
                                    else
                                        intemp = await _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                                            .Where((a, b) => b.CompanyId == item.CompanyId)
                                            .OrderBy((a, b) => b.CreateTime, OrderByType.Desc).FirstAsync();

                                    var inOrderDetails = new SALE_OrderDetail()
                                    {
                                        Discount = 100,
                                        CustSalesMan = "",
                                        CustStyleNo = "",
                                        CreateTime = DateTime.Now,
                                        Creator = item.Creator,
                                        KeyId = intemp.KeyId,
                                        PhotoUrl = detail.PhotoUrl,
                                        TenantId = item.TenantId,
                                        UnitName = "",
                                        CalQty = 0,
                                        RecordId = Guid.NewGuid(),
                                        MaterialId = detail.MaterialId,
                                        ColorName = detail.ColorName,
                                        SizeName = detail.SizeName,
                                        Price = detail.Price,
                                        DealQty = (int)itemQty,
                                        MaterialName = detail.MaterialName,
                                        MaterialNo = detail.MaterialNo,
                                        OrgPrice = detail.Price,
                                        RecordType = 1,
                                        Remark = "入库单自动补数",
                                        remPrice = detail.Price,
                                        Tax = detail.Tax,
                                        Qty = (int)itemQty,
                                        DescQty = 0,
                                        EntradaQty = (int)itemQty,
                                        DespachoQty = 0,
                                    };
                                    inOrderDetails.Total = inOrderDetails.Price * inOrderDetails.Qty * (1 + inOrderDetails.Tax / 100);
                                    inOrderDetails.DealTotal = inOrderDetails.Total;
                                    inOrderDetails.OrgTotal = inOrderDetails.Total;
                                    inOrderDetails.Taxprice = inOrderDetails.Price * inOrderDetails.Qty * (inOrderDetails.Tax / 100);
                                    inOrderDetails.OrderId = _client.Queryable<SALE_OrderDetail>().Where(t => t.KeyId == inOrderDetails.KeyId).Count() + 1;

                                    var inRelated = new MS_BillSourceRelated() { Id = Guid.NewGuid(), BillId = item.Id, BillDetailId = detail.Id, BillType = item.BillType, SourceType = item.SourceBillType, Status = 1, TenantId = item.TenantId, Qty = itemQty, Wieght = 0, };
                                    insSaleDetails.Add(inOrderDetails);
                                    relatedIns.Add(inRelated);
                                }
                            }
                        }
                    }
                }
                if (relatedIns.Count > 0)
                    await _client.Insertable(relatedIns).ExecuteCommandAsync();
                if (relatedDel.Count > 0)
                    await _client.Deleteable(relatedDel).ExecuteCommandAsync();
                if (orderDetails.Count > 0)
                    await _client.Updateable(orderDetails).ExecuteCommandAsync();
                if (insSaleDetails.Count > 0)
                    await _client.Insertable(insSaleDetails).ExecuteCommandAsync();

                var sales = orderDetails.Select(t => t.KeyId).Distinct().ToList();
                foreach (var keyId in sales)
                {
                    _client.Ado.UseStoredProcedure().ExecuteCommand("Pro_SaleOrder_SyncQty", new { Id = keyId });
                }
                var sourceBillNos = await _client.Queryable<MS_BillSourceRelated, SALE_Order>((a, b) => new object[] { JoinType.Left, a.SourceBillId == b.KeyId }).Where((a, b) => a.BillId == item.Id).Select((a, b) => b.BillNo).Distinct().ToListAsync();
                item.SourceBillNo = string.Join(",", sourceBillNos);
                await _client.Updateable(item).ExecuteCommandAsync();

                speed++;
            }
            return new BalResult(true, speed.ToString());
        }
        /// <summary>
        /// 获取物料出入库汇总
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="matIds"></param>
        /// <param name="isManual">true出库，false入库</param>
        /// <returns></returns>
        public async Task<List<MateSkuSummaryModel>> GetMatAllStroge(UserToken userToken, List<Guid> matIds)
        {
            var query = _client.Queryable<MS_Stroge, MS_StrogeDetail>((a, b) => new object[] { JoinType.Left, a.Id == b.StrogeId })
                .GroupBy((a, b) => new { a.SourceBillType, b.MaterialId, b.ColorName, b.SizeName, b.Specs, })
                .Where((a, b) => a.TenantId == userToken.TenantId && a.Status > 0 && matIds.Contains(b.MaterialId))
                .Select((a, b) => new MateSkuSummaryModel
                {
                    SourceBillType = a.SourceBillType,
                    Id = b.MaterialId,
                    ColorName = b.ColorName,
                    SizeName = b.SizeName,
                    SpecsName = b.Specs,
                    TotalQty = SqlFunc.AggregateSum(b.Qty),
                    DescQty = SqlFunc.AggregateSum(b.DescQty),
                    InStockQty = SqlFunc.AggregateSum(b.EntradaQty),
                    OutStockQty = SqlFunc.AggregateSum(b.DespachoQty),
                    TotalPrice = SqlFunc.AggregateSum(b.Total),
                });

            return await query.ToListAsync();
        }
        public async Task<PageDataModel<MSStrogeDetailReportModel>> GetStrogeDetailReport(UserToken userToken, SaleProReportSeachModel model)
        {
            var sourceBillType = StringHelper.StrSplitInt(model.SourceBillType, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.ClassId == model.ClassId && SqlFunc.Length(d.CompanyName) > 0 && SqlFunc.Between(b.BillDate, model.BeginDate, model.EndDate))
                .Where((a, b, c, d, e) => b.SourceBillType / 10 != 3 || b.SourceBillType / 10 != 6)
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.MaterialNo), (a, b, c) => c.MaterialNo.Contains(model.MaterialNo) || c.CompanyMaterialNo.Contains(model.MaterialNo) || c.MaterialName.Contains(model.MaterialNo))
                .WhereIF(!string.IsNullOrEmpty(model.ColorName), (a, b, c) => a.ColorName.Contains(model.ColorName))
                .WhereIF(!string.IsNullOrEmpty(model.SizeName), (a, b, c) => a.SizeName.Contains(model.SizeName))
                .WhereIF(!string.IsNullOrEmpty(model.SourceBillType), (a, b, c) => sourceBillType.Contains(b.SourceBillType))
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                ;

            var totals = await query.Clone()
                .Select((a, b, c, d, e) => new { Counts = SqlFunc.AggregateCount(1), TotalPrice = SqlFunc.AggregateSum(a.Total), TotalQty = SqlFunc.AggregateSum(a.Qty), DescQty = SqlFunc.AggregateSum(a.DescQty), DespachoQty = SqlFunc.AggregateSum(a.DespachoQty), EntradaQty = SqlFunc.AggregateSum(a.EntradaQty) }).FirstAsync();

            var data = await query.Clone()
                .Select((a, b, c, d, e) => new MSStrogeDetailReportModel
                {
                    BillDate = b.BillDate,
                    BillNo = b.BillNo,
                    BillType = b.BillType,
                    MaterialId = a.MaterialId,
                    SourceBillNo = b.SourceBillNo,
                    SourceBillType = b.SourceBillType,
                    CompanyId = b.CompanyId,
                    CompanyName = d.CompanyName,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price * (1 + a.Tax / 100),
                    Total = a.Total,
                    Qty = a.Qty,
                    EntradaQty = a.EntradaQty,
                    DespachoQty = a.DespachoQty,
                    Specs = a.Specs,
                    Remark = a.Remark,
                    OrderId = e.OrderId,
                    DcNo = b.DcNo,
                    StrogeId = a.StrogeId,
                    ClassId = b.ClassId,
                    DepotId = b.DepotId,
                    VatNo = a.VatNo,
                    Weight = a.Weight,
                    PhotoUrl = c.PhotoUrl,
                    HandmanId = b.HandmanId,
                    Handman = b.Handman,
                    Id = a.Id,
                    UnitName = a.UnitName,
                    UseProductNo = a.UseProductNo,
                    PositionNo = a.PositionNo,
                }).MergeTable()
                .OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.BillDate, t.MaterialNo, t.ColorName, t.OrderId, t.Specs, })
                .OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                .ToPageListAsync(model.PageIndex, model.PageSize);

            return new PageDataModel<MSStrogeDetailReportModel>()
            {
                DataList = data,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
                PageTotalPrice = data.Sum(t => t.Total),
                PageTotalQty = data.Sum(t => t.Qty),
                Total = totals.Counts,
                TotalPrice = totals.TotalPrice,
                TotalQty = totals.TotalQty,
                TotalDescQty = totals.DescQty,
                TotalDespachoQty = totals.DespachoQty,
                TotalEntradaQty = totals.EntradaQty,
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MaterialSkuStrogeTotalModel>> GetStrogeTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "4,5,6,7", Key = model.Key, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = model.PageIndex, PageSize = model.PageSize, }, userToken.Token);

            var result = new List<MaterialSkuStrogeTotalModel>();

            var saleType = new int[] { 4, 5, 6, 7 };
            foreach (var d in finance.DataList)
            {
                var item = new MaterialSkuStrogeTotalModel()
                {
                    CompanyName = d.CompanyName,
                    SaleCompanyName = d.CompanyName,
                    SourceBillNo = d.RelatedBillNo,
                    BillDate = d.TransactionDate,
                    BillType = (int)d.PayType,
                    BillNo = d.FlowNo,
                    PayPrice = d.Amount,
                    Remark = d.Remark,
                };
                if (saleType.Contains(item.BillType))
                {
                    item.CompanyName = "";
                }
                else
                {
                    item.SaleCompanyName = "";
                }
                result.Add(item);
            }
            var pageSize = model.PageSize - finance.DataList.Count;
            var total = finance.Total;
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 21, 22, 23, 24, 25, 11, 12, 13, 14, };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                //.GroupBy((a, b, c) => new { c.MaterialName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && b.ClassId == 0 && SqlFunc.Length(d.CompanyName) > 0 /*&& sourceBillType.Contains(b.SourceBillType)*/ && SqlFunc.Between(b.BillDate, model.BeginDate, model.EndDate))

                .Where((a, b, c, d, e) => b.SourceBillType / 10 != 3 || b.SourceBillType / 10 != 6)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new
                {
                    b.BillDate,
                    b.BillNo,
                    b.BillType,
                    a.MaterialId,
                    b.SourceBillNo,
                    b.SourceBillType,
                    b.CompanyId,
                    d.CompanyName,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price,
                    Qty = a.Qty,
                    a.EntradaQty,
                    a.DespachoQty,
                    SpecsName = a.Specs,
                    Remark = a.Remark,
                    Sort = e.OrderId,
                });
            total += query.Count();
            if (pageSize > 0)
            {
                var data = await query.MergeTable()
                    //.OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.MaterialNo, t.ColorName, t.Sort, t.SpecsName })
                    //.OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                    .ToOffsetPageAsync(model.PageIndex, pageSize);

                foreach (var d in data)
                {
                    var item = new MaterialSkuStrogeTotalModel()
                    {
                        ColorName = d.ColorName,
                        Remark = d.Remark,
                        SizeName = d.SizeName,
                        Sort = d.Sort,
                        MaterialName = d.MaterialName,
                        MaterialNo = d.MaterialNo,
                        Price = d.Price,
                        Qty = d.Qty,
                        EntradaQty = d.EntradaQty,
                        DespachoQty = d.DespachoQty,
                        CompanyName = d.CompanyName,
                        SpecsName = d.SpecsName,
                        CompanyMaterialNo = d.CompanyMaterialNo,
                        TotalPrice = d.Price * d.Qty,
                        SaleCompanyName = d.CompanyName,
                        SourceBillNo = d.SourceBillNo,
                        BillDate = d.BillDate,
                        BillType = d.BillType,
                        BillNo = d.BillNo,
                    };
                    if (d.SourceBillType == 21 || d.SourceBillType == 23)
                        item.CompanyName = "";
                    else
                        item.SaleCompanyName = "";
                    result.Add(item);
                }
            }

            result = result.OrderBy(t => t.Sort).OrderBy(t => t.ColorName).OrderBy(t => t.MaterialNo).OrderBy(t => t.CompanyName).OrderByDescending(t => t.BillDate).ToList();

            return new PageDataModel<MaterialSkuStrogeTotalModel>()
            {
                DataList = result,
                Total = total,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
            };
        }
        public async Task<PageDataModel<MaterialSkuStrogeTotalModel>> GetTransferTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var result = new List<MaterialSkuStrogeTotalModel>();

            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 21, 22, 23, 24, 25, 11, 12, 13, 14, };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, HR_Dept, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.DepotId == d.DeptID, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                //.GroupBy((a, b, c) => new { c.MaterialName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && b.ClassId == 0 && SqlFunc.Length(d.DeptName) > 0 /*&& sourceBillType.Contains(b.SourceBillType)*/ && SqlFunc.Between(b.BillDate, model.BeginDate, model.EndDate))

                .Where((a, b, c, d, e) => b.SourceBillType / 10 == 3)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.DeptName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new
                {
                    b.CreateTime,
                    b.BillNo,
                    b.BillType,
                    a.MaterialId,
                    b.SourceBillNo,
                    b.SourceBillType,
                    b.CompanyId,
                    d.DeptName,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price,
                    Qty = a.Qty,
                    a.EntradaQty,
                    a.DespachoQty,
                    SpecsName = a.Specs,
                    Remark = a.Remark,
                    Sort = e.OrderId,
                });
            var total = query.Count();
            var data = await query.MergeTable()
                //.OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.MaterialNo, t.ColorName, t.Sort, t.SpecsName })
                //.OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                .ToOffsetPageAsync(model.PageIndex, model.PageSize);

            foreach (var d in data)
            {
                var item = new MaterialSkuStrogeTotalModel()
                {
                    ColorName = d.ColorName,
                    Remark = d.Remark,
                    SizeName = d.SizeName,
                    Sort = d.Sort,
                    MaterialName = d.MaterialName,
                    MaterialNo = d.MaterialNo,
                    Price = d.Price,
                    Qty = d.Qty,
                    EntradaQty = d.EntradaQty,
                    DespachoQty = d.DespachoQty,
                    CompanyName = d.DeptName,
                    SpecsName = d.SpecsName,
                    CompanyMaterialNo = d.CompanyMaterialNo,
                    TotalPrice = d.Price * d.Qty,
                    SaleCompanyName = d.DeptName,
                    SourceBillNo = d.SourceBillNo,
                    BillDate = d.CreateTime,
                    BillType = d.BillType,
                    BillNo = d.BillNo,
                };
                if (d.SourceBillType == 21 || d.SourceBillType == 23)
                    item.CompanyName = "";
                else
                    item.SaleCompanyName = "";
                result.Add(item);
            }

            result = result.OrderBy(t => t.Sort).OrderBy(t => t.ColorName).OrderBy(t => t.MaterialNo).OrderBy(t => t.CompanyName).OrderByDescending(t => t.BillDate).ToList();

            return new PageDataModel<MaterialSkuStrogeTotalModel>()
            {
                DataList = result,
                Total = total,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
            };
        }
        public async Task<List<MaterialSkuStrogeTotalModel>> GetStrogeTotalSummary(UserToken userToken, SaleProReportSeachModel model)
        {

            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 21, 22, 23, 24, 25, 11, 12, 13, 14, };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                .GroupBy((a, b, c, d, e) => new { a.MaterialId, c.MaterialName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, a.Specs, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && b.ClassId == 0 && SqlFunc.Length(d.CompanyName) > 0 /*&& sourceBillType.Contains(b.SourceBillType)*/ && SqlFunc.Between(b.BillDate, model.BeginDate, model.EndDate))
                .Where((a, b, c, d, e) => b.SourceBillType / 10 != 3 || b.SourceBillType / 10 != 6)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new MaterialSkuStrogeTotalModel
                {
                    MaterialId = a.MaterialId,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Qty = SqlFunc.AggregateSum(a.Qty),
                    EntradaQty = SqlFunc.AggregateSum(a.EntradaQty),
                    DespachoQty = SqlFunc.AggregateSum(a.DespachoQty),
                    SpecsName = a.Specs,
                    Sort = SqlFunc.AggregateSum(e.OrderId),
                });
            var total = query.Count();
            var data = await query.MergeTable().OrderBy(a => new { a.MaterialId, a.ColorName, a.Sort, a.SpecsName, })
                .ToListAsync();

            return data;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MaterialSkuStrogeTotalModel>> GetStrogeProTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "8,9,10,11", Key = model.Key, CompanyType = 2, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = model.PageIndex, PageSize = model.PageSize, }, userToken.Token);
            var data = new List<MaterialSkuStrogeTotalModel>();

            var saleType = new int[] { 4, 5, 6, 7 };
            var companyId = finance.DataList.Select(t => t.CompanyId).ToList();
            var companyList = await _client.Queryable<BAS_Company>().Where(t => companyId.Contains(t.CompanyId) && t.SupplyType == 1 && t.CompanyType == 2).ToListAsync();
            foreach (var d in finance.DataList)
            {
                if (companyList.Where(t => t.CompanyId == d.CompanyId).Any())
                {
                    var item = new MaterialSkuStrogeTotalModel()
                    {
                        CompanyName = d.CompanyName,
                        SaleCompanyName = d.CompanyName,
                        SourceBillNo = d.RelatedBillNo,
                        BillDate = d.TransactionDate,
                        BillType = (int)d.PayType,
                        BillNo = d.FlowNo,
                        PayPrice = d.Amount,
                        Remark = d.Remark,
                    };
                    if (saleType.Contains(item.BillType))
                    {
                        item.CompanyName = "";
                    }
                    else
                    {
                        item.SaleCompanyName = "";
                    }
                    data.Add(item);
                }
            }
            var pageSize = model.PageSize - finance.DataList.Count;
            var total = finance.Total;
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 14 };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, a.Qty, b.BillType, a.Specs, a.Remark, e.OrderId, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && c.ClassId == 0 && d.CompanyType == 2 && d.SupplyType == 2 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))

                .Where((a, b, c, d, e) => b.SourceBillType / 10 != 3 || b.SourceBillType / 10 != 6)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new MaterialSkuStrogeTotalModel
                {
                    BillDate = b.BillDate,
                    CompanyId = b.CompanyId,
                    CompanyName = d.CompanyName,
                    MaterialId = a.MaterialId,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price,
                    PurPrice = c.Price,
                    Qty = SqlFunc.IIF(b.BillType == 40, 0 - a.Qty, a.Qty),
                    TotalPrice = a.Price * a.Qty * SqlFunc.IIF(b.BillType == 40, -1, 1),
                    SpecsName = a.Specs,
                    Remark = a.Remark,
                    Sort = e.OrderId,
                    BillNo = b.BillNo,
                    BillType = b.BillType,
                    DespachoQty = a.DespachoQty,
                    EntradaQty = a.EntradaQty,
                    Weight = a.Weight,
                    SourceBillNo = b.SourceBillNo,
                    SourceBillType = b.SourceBillType,
                });
            total += query.Count();
            if (pageSize > 0)
            {
                var dataStr = await query.MergeTable()//.OrderBy(t => new { t.MaterialNo, t.ColorName, t.Sort, t.SpecsName })
                    .ToPageListAsync(model.PageIndex, pageSize);
                data.AddRange(dataStr);
            }
            var matIds = data.Select(t => t.MaterialId).Distinct().ToList();
            var saleCompanyIds = data.Where(t => t.SourceBillType / 10 == 2).Select(t => t.CompanyId).ToList();
            //var saleLasts = await _client.Queryable<SALE_Order, SALE_OrderDetail>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
            //    .Where((a, b) => a.TenantId == userToken.TenantId && saleCompanyIds.Contains(a.CompanyId) && matIds.Contains(b.MaterialId)).ToListAsync();
            //var purCompanyIds = data.Where(t => t.SourceBillType / 10 == 1).Select(t => t.CompanyId).ToList();
            //var purLasts = await _client.Queryable<MS_Purchase, MS_PurchaseDetail>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
            //    .Where((a, b) => a.TenantId == userToken.TenantId && saleCompanyIds.Contains(a.CompanyId) && matIds.Contains(b.MaterialId)).ToListAsync();

            var temp = data.Where(t => t.Price == 0).ToList();
            foreach (var item in temp)
            {
                if (item.SourceBillType / 10 == 1)
                {
                }
                else if (item.SourceBillType / 10 == 2)
                {
                    var m = await _client.Queryable<SALE_OrderDetail, SALE_Order>((a, b) => new object[] { JoinType.Left, a.KeyId == b.KeyId })
                         .Where((a, b) => a.TenantId == userToken.TenantId && b.CompanyId == item.CompanyId && a.MaterialId == item.MaterialId).OrderBy((a, b) => b.BillDate, OrderByType.Desc).FirstAsync();
                    item.Price = m.Price;
                }
                if (item.Price == 0)
                    item.Price = item.PurPrice;
            }

            data = data.OrderBy(t => t.Sort).OrderBy(t => t.ColorName).OrderBy(t => t.MaterialNo).OrderBy(t => t.CompanyName).OrderByDescending(t => t.BillDate).ToList();

            return new PageDataModel<MaterialSkuStrogeTotalModel>()
            {
                DataList = data,
                Total = total,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MaterialSkuStrogeTotalModel>> GetStrogeMatTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "8,9,10,11", Key = model.Key, CompanyType = 2, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = model.PageIndex, PageSize = model.PageSize, }, userToken.Token);
            var saleType = new int[] { 4, 5, 6, 7 };
            var companyId = finance.DataList.Select(t => t.CompanyId).ToList();
            var companyList = await _client.Queryable<BAS_Company>().Where(t => companyId.Contains(t.CompanyId) && t.SupplyType == 2 && t.CompanyType == 2).ToListAsync();
            var data = new List<MaterialSkuStrogeTotalModel>();

            foreach (var d in finance.DataList)
            {
                if (companyList.Where(t => t.CompanyId == d.CompanyId).Any())
                {
                    var item = new MaterialSkuStrogeTotalModel()
                    {
                        CompanyName = d.CompanyName,
                        SaleCompanyName = d.CompanyName,
                        SourceBillNo = d.RelatedBillNo,
                        BillDate = d.TransactionDate,
                        BillType = (int)d.PayType,
                        BillNo = d.FlowNo,
                        PayPrice = d.Amount,
                        Remark = d.Remark,
                    };
                    if (saleType.Contains(item.BillType))
                    {
                        item.CompanyName = "";
                    }
                    else
                    {
                        item.SaleCompanyName = "";
                    }
                    data.Add(item);
                }
            }
            var pageSize = model.PageSize - finance.DataList.Count;
            var total = finance.Total;
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 11, 14 };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && c.ClassId == 1 /*&& d.CompanyType == 2 && d.SupplyType == 2*/ && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key) && model.IsSccurate, (a, b, c, d, e) => SqlFunc.EndsWith(b.BillNo, model.Key) || SqlFunc.EndsWith(d.CompanyName, model.Key) || SqlFunc.EndsWith(c.MaterialNo, model.Key) || SqlFunc.EndsWith(c.CompanyMaterialNo, model.Key) || SqlFunc.EndsWith(c.MaterialName, model.Key))
                .WhereIF(!string.IsNullOrEmpty(model.Key) && !model.IsSccurate, (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new MaterialSkuStrogeTotalModel
                {
                    BillDate = SqlFunc.ToDateShort(b.BillDate),
                    CompanyName = d.CompanyName,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price,
                    Qty = SqlFunc.IIF(b.BillType == 40, -a.Qty, a.Qty),
                    TotalPrice = a.Price * a.Qty * SqlFunc.IIF(b.BillType == 40, -1, 1),
                    SpecsName = a.Specs,
                    Remark = a.Remark,
                    Sort = e.OrderId,
                    DespachoQty = a.DespachoQty,
                    EntradaQty = a.EntradaQty,
                    Weight = a.Weight,
                    BillNo = b.BillNo,
                    BillType = b.BillType,
                    SourceBillNo = b.SourceBillNo,
                    SourceBillType = b.SourceBillType,
                }).MergeTable()
                .GroupBy(t => new { t.BillDate, t.CompanyName, t.MaterialNo, t.CompanyMaterialNo, t.ColorName, t.SizeName, t.MaterialName, t.Price, t.SpecsName, t.Remark, t.BillNo, t.BillType, t.SourceBillNo, t.Sort, t.SourceBillType, })
                .Select(t => new MaterialSkuStrogeTotalModel
                {
                    BillDate = t.BillDate,
                    CompanyName = t.CompanyName,
                    MaterialNo = t.MaterialNo,
                    CompanyMaterialNo = t.CompanyMaterialNo,
                    ColorName = t.ColorName,
                    SizeName = t.SizeName,
                    MaterialName = t.MaterialName,
                    Price = t.Price,
                    Qty = SqlFunc.AggregateSum(t.Qty),
                    TotalPrice = SqlFunc.AggregateSum(t.TotalPrice),
                    SpecsName = t.SpecsName,
                    Remark = t.Remark,
                    Sort = SqlFunc.AggregateSum(t.Sort),
                    DespachoQty = SqlFunc.AggregateSum(t.DespachoQty),
                    EntradaQty = SqlFunc.AggregateSum(t.EntradaQty),
                    Weight = SqlFunc.AggregateSum(t.Weight),
                    BillNo = t.BillNo,
                    BillType = t.BillType,
                    SourceBillNo = t.SourceBillNo,
                    SourceBillType = t.SourceBillType,
                });
            total += query.Count();
            if (pageSize > 0)
            {
                var dataStr = await query//.OrderBy(t => new { t.MaterialNo, t.ColorName, t.Sort, t.SpecsName })
                    .ToPageListAsync(model.PageIndex, pageSize);
                data.AddRange(dataStr);
            }
            data = data.OrderBy(t => t.Sort).OrderBy(t => t.ColorName).OrderBy(t => t.MaterialNo).OrderBy(t => t.CompanyName).OrderByDescending(t => t.BillDate).ToList();

            return new PageDataModel<MaterialSkuStrogeTotalModel>()
            {
                DataList = data,
                Total = total,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
            };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MaterialSkuStrogeTotalModel>> GetOutsourcMatTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 51, 52, 53, 54, 81, 82, 83, 84, };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                .GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.DespachoQty, a.EntradaQty, a.Specs, a.Remark, e.OrderId, a.Weight, b.BillNo, b.SourceBillNo, b.SourceBillType, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && sourceBillType.Contains(b.SourceBillType) && c.ClassId == 1 && d.CompanyType == 3 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key) && model.IsSccurate, (a, b, c, d, e) => SqlFunc.EndsWith(b.BillNo, model.Key) || SqlFunc.EndsWith(d.CompanyName, model.Key) || SqlFunc.EndsWith(c.MaterialNo, model.Key) || SqlFunc.EndsWith(c.CompanyMaterialNo, model.Key) || SqlFunc.EndsWith(c.MaterialName, model.Key))
                .WhereIF(!string.IsNullOrEmpty(model.Key) && !model.IsSccurate, (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new MaterialSkuStrogeTotalModel
                {
                    BillDate = b.BillDate,
                    CompanyName = d.CompanyName,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price,
                    Qty = SqlFunc.IIF(b.BillType == 40, 0 - a.Qty, a.Qty),
                    TotalPrice = a.Price * a.Qty * SqlFunc.IIF(b.BillType == 40, -1, 1),
                    DespachoQty = SqlFunc.IIF(b.BillType == 40, 0 - a.DespachoQty, a.DespachoQty),
                    EntradaQty = SqlFunc.IIF(b.BillType == 40, a.EntradaQty, 0 - a.EntradaQty),
                    SpecsName = a.Specs,
                    Remark = a.Remark,
                    Sort = e.OrderId,
                    Weight = a.Weight,
                    BillNo = b.BillNo,
                    BillType = b.BillType,
                    SourceBillNo = b.SourceBillNo,
                    SourceBillType = b.SourceBillType,
                });
            var total = query.Count();
            var data = await query.MergeTable().OrderBy(t => new { t.MaterialNo, t.ColorName, t.Sort, t.SpecsName }).ToPageListAsync(model.PageIndex, model.PageSize);

            return new PageDataModel<MaterialSkuStrogeTotalModel>()
            {
                DataList = data,
                Total = total,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MaterialSkuStrogeTotalModel>> GetOutsourcProTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var sourceBillType = new int[] { 51, 52, 53 };
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, })
                .GroupBy((a, b, c, d, e) => new { b.BillNo, b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, a.Weight, b.SourceBillNo, b.SourceBillType, })
                .Where((a, b, c, d, e) => a.TenantId == userToken.TenantId && b.Status >= 0 && sourceBillType.Contains(b.SourceBillType) && c.ClassId == 0 && d.CompanyType == 3 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))

                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .Select((a, b, c, d, e) => new MaterialSkuStrogeTotalModel
                {
                    BillNo = b.BillNo,
                    BillType = 0,
                    BillDate = b.BillDate,
                    CompanyName = d.CompanyName,
                    MaterialNo = a.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price,
                    Qty = SqlFunc.IIF(b.BillType == 40, -a.Qty, a.Qty),
                    TotalPrice = a.Price * a.Qty * SqlFunc.IIF(b.BillType == 40, -1, 1),
                    SpecsName = a.Specs,
                    Remark = a.Remark,
                    Sort = e.OrderId,
                    Weight = a.Weight,
                    SourceBillNo = b.SourceBillNo,
                    SourceBillType = b.SourceBillType,
                });
            var total = query.Count();
            var data = await query.MergeTable().OrderBy(t => new { t.MaterialNo, t.ColorName, t.Sort, t.SpecsName }).ToPageListAsync(model.PageIndex, model.PageSize);

            return new PageDataModel<MaterialSkuStrogeTotalModel>()
            {
                DataList = data,
                Total = total,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
            };
        }

        /// <summary>
        /// 根据款号查询出货汇总
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MSDetailTotalByMatNoModel>> GetSaleStrogeDetailByMatNoTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[]
              {
                JoinType.Left, a.StrogeId == b.Id,
                JoinType.Left, a.MaterialId == c.MaterialId,
                JoinType.Left, b.CompanyId == d.CompanyId,
                JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId,
              })
                .Where((a, b, c) => a.TenantId == userToken.TenantId && b.Status > 0 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate) && b.SourceBillType / 10 == 2)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(model.PurchaseMan != Guid.Empty, (a, b, c) => b.Creator == model.PurchaseMan)
                .WhereIF(!string.IsNullOrEmpty(model.MaterialNo), (a, b, c) => c.MaterialNo.Contains(model.MaterialNo) || c.CompanyMaterialNo.Contains(model.MaterialNo) || c.MaterialName.Contains(model.MaterialNo))
                .WhereIF(!string.IsNullOrEmpty(model.ColorName), (a, b, c) => a.ColorName == model.ColorName)
                .WhereIF(!string.IsNullOrEmpty(model.SizeName), (a, b, c) => a.SizeName == model.SizeName)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.CompanyName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))

                .GroupBy((a, b, c, d, e) => new { a.MaterialId, c.MaterialNo, c.CompanyMaterialNo, c.MaterialName, c.PhotoUrl, a.ColorName, })
                .Select((a, b, c, d, e) => new MSDetailTotalByMatNoModel
                {
                    MaterialId = a.MaterialId,
                    MaterialNo = c.MaterialNo,
                    CompanyMaterialNo = c.CompanyMaterialNo,
                    MaterialName = c.MaterialName,
                    PhotoUrl = c.PhotoUrl,
                    ColorName = a.ColorName,
                    Qty = SqlFunc.AggregateSum(a.Qty),
                    EntradaQty = SqlFunc.AggregateSum(a.EntradaQty),
                    DespachoQty = SqlFunc.AggregateSum(a.DespachoQty),
                    DescQty = SqlFunc.AggregateSum(a.DescQty),
                    Total = SqlFunc.AggregateSum(a.Total),
                }).MergeTable();

            var totals = await query.Clone()
                .Select((a) => new { Counts = SqlFunc.AggregateCount(1), TotalPrice = SqlFunc.AggregateSum(a.Total), TotalQty = SqlFunc.AggregateSum(a.Qty), DescQty = SqlFunc.AggregateSum(a.DescQty), DespachoQty = SqlFunc.AggregateSum(a.DespachoQty), EntradaQty = SqlFunc.AggregateSum(a.EntradaQty) }).FirstAsync();

            var data = await query.Clone()
                .OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.MaterialNo })
                .OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                .ToPageListAsync(model.PageIndex, model.PageSize);

            var matIds = data.Select(t => t.MaterialId).ToList();
            return new PageDataModel<MSDetailTotalByMatNoModel>()
            {
                DataList = data,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
                PageTotalPrice = data.Sum(t => t.Total),
                PageTotalQty = data.Sum(t => t.Qty),
                Total = totals.Counts,
                TotalPrice = totals.TotalPrice,
                TotalQty = totals.TotalQty,
                TotalDescQty = totals.DescQty,
                TotalDespachoQty = totals.DespachoQty,
                TotalEntradaQty = totals.EntradaQty,
            };
        }
        /// <summary>
        /// 根据客户查询出货汇总
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MSDetailTotalByCompanyModel>> GetSaleStrogeDetailByCompanyTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail>((a, b, c, d, e) => new object[]
              {
                JoinType.Left, a.StrogeId == b.Id,
                JoinType.Left, a.MaterialId == c.MaterialId,
                JoinType.Left, b.CompanyId == d.CompanyId,
                JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId,
              })
                .Where((a, b, c) => a.TenantId == userToken.TenantId && b.Status > 0 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate) && b.SourceBillType / 10 == 2)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                //.WhereIF(model.PurchaseMan != Guid.Empty, (a, b, c) => b.Creator == model.PurchaseMan)
                .WhereIF(!string.IsNullOrEmpty(model.MaterialNo), (a, b, c) => c.MaterialNo.Contains(model.MaterialNo) || c.CompanyMaterialNo.Contains(model.MaterialNo) || c.MaterialName.Contains(model.MaterialNo))
                .WhereIF(!string.IsNullOrEmpty(model.ColorName), (a, b, c) => a.ColorName == model.ColorName)
                .WhereIF(!string.IsNullOrEmpty(model.SizeName), (a, b, c) => a.SizeName == model.SizeName)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => d.CompanyName.Contains(model.Key))
                .GroupBy((a, b, c, d, e) => new { d.CompanyName, })
                .Select((a, b, c, d, e) => new MSDetailTotalByCompanyModel
                {
                    CompanyName = d.CompanyName,
                    Qty = SqlFunc.AggregateSum(a.Qty),
                    EntradaQty = SqlFunc.AggregateSum(a.EntradaQty),
                    DespachoQty = SqlFunc.AggregateSum(a.DespachoQty),
                    DescQty = SqlFunc.AggregateSum(a.DescQty),
                    Total = SqlFunc.AggregateSum(a.Total),
                }).MergeTable();

            var totals = await query.Clone()
                .Select((a) => new { Counts = SqlFunc.AggregateCount(1), TotalPrice = SqlFunc.AggregateSum(a.Total), TotalQty = SqlFunc.AggregateSum(a.Qty), DescQty = SqlFunc.AggregateSum(a.DescQty), DespachoQty = SqlFunc.AggregateSum(a.DespachoQty), EntradaQty = SqlFunc.AggregateSum(a.EntradaQty) }).FirstAsync();

            var data = await query.Clone()
                .OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.CompanyName })
                .OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                .ToPageListAsync(model.PageIndex, model.PageSize);

            return new PageDataModel<MSDetailTotalByCompanyModel>()
            {
                DataList = data,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
                PageTotalPrice = data.Sum(t => t.Total),
                PageTotalQty = data.Sum(t => t.Qty),
                Total = totals.Counts,
                TotalPrice = totals.TotalPrice,
                TotalQty = totals.TotalQty,
                TotalDescQty = totals.DescQty,
                TotalDespachoQty = totals.DespachoQty,
                TotalEntradaQty = totals.EntradaQty,
            };
        }
        /// <summary>
        /// 根据出货人查询出货汇总
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MSDetailTotalByMemberModel>> GetSaleStrogeDetailByMemberTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, HR_Member, BAS_SizeDetail>((a, b, c, d, e) => new object[]
              {
                JoinType.Left, a.StrogeId == b.Id,
                JoinType.Left, a.MaterialId == c.MaterialId,
                JoinType.Left, b.Creator == d.UserId && b.TenantId == d.TenantId,
                JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId,
              })
                .Where((a, b, c) => a.TenantId == userToken.TenantId && b.Status > 0 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate) && b.SourceBillType / 10 == 2)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                //.WhereIF(model.CompanyId != Guid.Empty, (a, b, c) => b.CompanyId == model.CompanyId)
                .WhereIF(model.PurchaseMan != Guid.Empty, (a, b, c, d, e) => d.Id == model.PurchaseMan)
                .WhereIF(!string.IsNullOrEmpty(model.MaterialNo), (a, b, c) => c.MaterialNo.Contains(model.MaterialNo) || c.CompanyMaterialNo.Contains(model.MaterialNo) || c.MaterialName.Contains(model.MaterialNo))
                .WhereIF(!string.IsNullOrEmpty(model.ColorName), (a, b, c) => a.ColorName == model.ColorName)
                .WhereIF(!string.IsNullOrEmpty(model.SizeName), (a, b, c) => a.SizeName == model.SizeName)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.MemberName.Contains(model.Key))
                .GroupBy((a, b, c, d, e) => new { d.MemberName, })
                .Select((a, b, c, d, e) => new MSDetailTotalByMemberModel
                {
                    MemberName = d.MemberName,
                    Qty = SqlFunc.AggregateSum(a.Qty),
                    EntradaQty = SqlFunc.AggregateSum(a.EntradaQty),
                    DespachoQty = SqlFunc.AggregateSum(a.DespachoQty),
                    DescQty = SqlFunc.AggregateSum(a.DescQty),
                    Total = SqlFunc.AggregateSum(a.Total),
                }).MergeTable();

            var totals = await query.Clone()
                .Select((a) => new { Counts = SqlFunc.AggregateCount(1), TotalPrice = SqlFunc.AggregateSum(a.Total), TotalQty = SqlFunc.AggregateSum(a.Qty), DescQty = SqlFunc.AggregateSum(a.DescQty), DespachoQty = SqlFunc.AggregateSum(a.DespachoQty), EntradaQty = SqlFunc.AggregateSum(a.EntradaQty) }).FirstAsync();

            var data = await query.Clone()
                .OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.MemberName })
                .OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                .ToPageListAsync(model.PageIndex, model.PageSize);

            return new PageDataModel<MSDetailTotalByMemberModel>()
            {
                DataList = data,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
                PageTotalPrice = data.Sum(t => t.Total),
                PageTotalQty = data.Sum(t => t.Qty),
                Total = totals.Counts,
                TotalPrice = totals.TotalPrice,
                TotalQty = totals.TotalQty,
                TotalDescQty = totals.DescQty,
                TotalDespachoQty = totals.DespachoQty,
                TotalEntradaQty = totals.EntradaQty,
            };
        }
        /// <summary>
        /// 根据仓库查询出货汇总
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<PageDataModel<MSDetailTotalByDeptModel>> GetSaleStrogeDetailByDeptTotal(UserToken userToken, SaleProReportSeachModel model)
        {
            var depotStatus = StringHelper.StrSplitInt(model.DepotStatus, ",");
            var status = StringHelper.StrSplitInt(model.Status, ",");
            var query = _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, HR_Dept, BAS_SizeDetail>((a, b, c, d, e) => new object[]
              {
                JoinType.Left, a.StrogeId == b.Id,
                JoinType.Left, a.MaterialId == c.MaterialId,
                JoinType.Left, b.DepotId == d.DeptID,
                JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId,
              })
                .Where((a, b, c) => a.TenantId == userToken.TenantId && b.Status > 0 && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate) && b.SourceBillType / 10 == 2)
                .WhereIF(!string.IsNullOrEmpty(model.DepotStatus), (a, b, c) => depotStatus.Contains(b.DepotStatus))
                .WhereIF(model.DeptId != Guid.Empty, (a, b, c) => b.DepotId == model.DeptId)
                //.WhereIF(model.PurchaseMan != Guid.Empty, (a, b, c) => b.Creator == model.PurchaseMan)
                .WhereIF(!string.IsNullOrEmpty(model.MaterialNo), (a, b, c) => c.MaterialNo.Contains(model.MaterialNo) || c.CompanyMaterialNo.Contains(model.MaterialNo) || c.MaterialName.Contains(model.MaterialNo))
                .WhereIF(!string.IsNullOrEmpty(model.ColorName), (a, b, c) => a.ColorName == model.ColorName)
                .WhereIF(!string.IsNullOrEmpty(model.SizeName), (a, b, c) => a.SizeName == model.SizeName)
                .WhereIF(!string.IsNullOrEmpty(model.Status), (a, b, c) => status.Contains(b.Status))
                .WhereIF(!string.IsNullOrEmpty(model.Key), (a, b, c, d, e) => b.BillNo.Contains(model.Key) || d.DeptName.Contains(model.Key) || c.MaterialNo.Contains(model.Key) || c.CompanyMaterialNo.Contains(model.Key) || c.MaterialName.Contains(model.Key))

                .GroupBy((a, b, c, d, e) => new { d.DeptName, })
                .Select((a, b, c, d, e) => new MSDetailTotalByDeptModel
                {
                    DeptName = d.DeptName,
                    Qty = SqlFunc.AggregateSum(a.Qty),
                    EntradaQty = SqlFunc.AggregateSum(a.EntradaQty),
                    DespachoQty = SqlFunc.AggregateSum(a.DespachoQty),
                    DescQty = SqlFunc.AggregateSum(a.DescQty),
                    Total = SqlFunc.AggregateSum(a.Total),
                }).MergeTable();

            var totals = await query.Clone()
                .Select((a) => new { Counts = SqlFunc.AggregateCount(1), TotalPrice = SqlFunc.AggregateSum(a.Total), TotalQty = SqlFunc.AggregateSum(a.Qty), DescQty = SqlFunc.AggregateSum(a.DescQty), DespachoQty = SqlFunc.AggregateSum(a.DespachoQty), EntradaQty = SqlFunc.AggregateSum(a.EntradaQty) }).FirstAsync();

            var data = await query.Clone()
                .OrderByIF(string.IsNullOrEmpty(model.SortType), t => new { t.DeptName })
                .OrderByIF(!string.IsNullOrEmpty(model.SortType), model.SortType)
                .ToPageListAsync(model.PageIndex, model.PageSize);

            return new PageDataModel<MSDetailTotalByDeptModel>()
            {
                DataList = data,
                PageSize = model.PageSize,
                PageIndex = model.PageIndex,
                PageTotalPrice = data.Sum(t => t.Total),
                PageTotalQty = data.Sum(t => t.Qty),
                Total = totals.Counts,
                TotalPrice = totals.TotalPrice,
                TotalQty = totals.TotalQty,
                TotalDescQty = totals.DescQty,
                TotalDespachoQty = totals.DespachoQty,
                TotalEntradaQty = totals.EntradaQty,
            };
        }
        /// <summary>
        /// 客户按明细对账
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ReconciliationDetailModel> GetCustomerReconciliationDetail(UserToken userToken, ReconciliationQueryModel model)
        {
            var companyAPI = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            var company = await companyAPI.GetById(model.CompanyId, userToken.Token);
            var customerBeginAmount = await companyAPI.CustomerBeginAmount(model.CompanyId, model.BeginDate, userToken.Token);
            var customerEndAmount = await companyAPI.CustomerBeginAmount(model.CompanyId, model.EndDate, userToken.Token);

            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "5,7,20", CompanyId = model.CompanyId, CompanyType = 1, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = 1, PageSize = 999999999, }, userToken.Token);
            var data = new ReconciliationDetailModel();
            data.FinanceDetails = new List<ReconciliationFinanceDetailModel>();
            data.SaleProductDetails = new List<ReconciliationProductDetailModel>();
            data.ReturnProductDetails = new List<ReconciliationProductDetailModel>();
            data.SaleOtherDetails = new List<ReconciliationDetailOtherModel>();

            foreach (var d in finance.DataList)
            {
                var remark = "";
                var Total = 0m;
                switch (d.PayType)
                {
                    case PayTypeEnum.SaleAdvPay:
                        remark = $"预付款";
                        Total = d.Amount;
                        break;
                    case PayTypeEnum.RechargeReward:
                        remark = $"充值奖励";
                        Total = d.Amount;
                        break;
                    case PayTypeEnum.SalAdvRefund:
                        remark = $"退预付款";
                        Total = d.Amount;
                        break;
                    default:
                        break;
                }
                data.FinanceDetails.Add(new ReconciliationFinanceDetailModel()
                {
                    DeptName = "",
                    AccountName = d.AccountName,
                    BillDate = d.TransactionDate,
                    BillNo = d.RelatedBillNo,
                    Remark = remark + (remark.Length > 0 ? "," : "") + d.Remark,
                    Total = Total,
                });
            }

            var query = await _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail, HR_Member, HR_Dept>((a, b, c, d, e, f, g) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((a, b, c, d, e, f, g) => a.TenantId == userToken.TenantId && b.Status >= 0 && (b.SourceBillType / 10 == 2 || b.SourceBillType == 0) /*&& d.CompanyType == 2 && d.SupplyType == 2*/ && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((a, b, c, d, e, f, g) => b.CompanyId == model.CompanyId)
                .Select((a, b, c, d, e, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    MaterialId = a.MaterialId,
                    PhotoUrl = c.PhotoUrl,
                    BillDate = SqlFunc.ToDateShort(b.BillDate),
                    MaterialNo = a.MaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price * (1 + a.Tax / 100),
                    Qty = a.Qty,
                    Total = a.Price * (1 + a.Tax / 100) * a.Qty,
                    Specs = a.Specs,
                    Remark = a.Remark,
                    BillNo = b.BillNo,
                }).MergeTable()
                .GroupBy(t => new { t.BillType, t.DeptName, t.MaterialId, t.PhotoUrl, t.BillDate, t.MaterialNo, t.ColorName, t.SizeName, t.MaterialName, t.Price, t.Specs, t.Remark, t.BillNo, })
                .Select(t => new
                {
                    BillType = t.BillType,
                    DeptName = t.DeptName,
                    MaterialId = t.MaterialId,
                    PhotoUrl = t.PhotoUrl,
                    BillDate = t.BillDate,
                    MaterialNo = t.MaterialNo,
                    ColorName = t.ColorName,
                    SizeName = t.SizeName,
                    MaterialName = t.MaterialName,
                    Price = t.Price,
                    Qty = SqlFunc.AggregateSum(t.Qty),
                    Total = SqlFunc.AggregateSum(t.Total),
                    Specs = t.Specs,
                    Remark = t.Remark,
                    BillNo = t.BillNo,
                }).ToListAsync();
            var saleData = query.Where(t => t.BillType == 40).ToList();
            var returnData = query.Where(t => t.BillType == 41).ToList();
            foreach (var item in saleData)
            {
                data.SaleProductDetails.Add(new ReconciliationProductDetailModel() { DeptName = item.DeptName, SizeName = item.SizeName, Specs = item.Specs, BillDate = item.BillDate, BillNo = item.BillNo, ColorName = item.ColorName, MaterialId = item.MaterialId, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, PhotoUrl = item.PhotoUrl, Price = item.Price, Qty = item.Qty, Remark = item.Remark, Total = item.Total, });
            }
            foreach (var item in returnData)
            {
                data.ReturnProductDetails.Add(new ReconciliationProductDetailModel() { DeptName = item.DeptName, SizeName = item.SizeName, Specs = item.Specs, BillDate = item.BillDate, BillNo = item.BillNo, ColorName = item.ColorName, MaterialId = item.MaterialId, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, PhotoUrl = item.PhotoUrl, Price = item.Price, Qty = -item.Qty, Remark = item.Remark, Total = -item.Total, });
            }

            var sale = await _client.Queryable<SALE_Order, Sale_OrderOtherReceivable, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.OrderId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status > 0 && (b.SmearMoney > 0 || (c.Amount > 0)) && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
                //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
                .Select((b, c, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = b.BillDate,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    MemberName = f.MemberName,
                    c.Amount,
                    c.TransactionName,
                    b.SmearMoney,
                }).ToListAsync();
            var saleCost = await _client.Queryable<SALE_Order, Sale_OrderAssociatedCost, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.OrderId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status > 0 && c.IsBear == true && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
                //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
                .Select((b, c, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = b.BillDate,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    MemberName = f.MemberName,
                    c.Amount,
                    TransactionName = c.BigKindName,
                    b.SmearMoney,
                }).ToListAsync();
            sale.AddRange(saleCost);
            foreach (var item in sale)
            {
                if (data.SaleOtherDetails.Where(t => t.BillNo == item.BillNo).Any() && item.Amount > 0)
                {
                    var temp = data.SaleOtherDetails.Where(t => t.BillNo == item.BillNo).First();
                    temp.OtherPrice += item.Amount;
                    temp.Total += item.Amount;
                    temp.OtherPriceRemark += $"{item.TransactionName}:{item.Amount}。";
                }
                else if (item.Amount > 0 || item.SmearMoney > 0)
                {
                    data.SaleOtherDetails.Add(new ReconciliationDetailOtherModel()
                    {
                        DeptName = item.DeptName,
                        BillDate = item.BillDate,
                        BillNo = item.BillNo,
                        Remark = item.Remark,
                        SmearMoney = item.SmearMoney,
                        SaleManName = item.MemberName,
                        Total = -item.SmearMoney + item.Amount,
                        OtherPrice = item.Amount,
                        //OtherPriceRemark = item.Amount > 0 ? $"{item.TransactionName}:{item.Amount}。" : "",
                        OtherPriceRemark = (item.SmearMoney > 0 ? $"抹零:{item.SmearMoney.ToString("F2")}" : "") + (item.Amount > 0 ? $"{item.TransactionName}:{item.Amount.ToString("F2")}。" : ""),
                    });
                }
            }
            data.FinanceDetails = data.FinanceDetails.OrderBy(t => t.BillDate).ToList();
            data.ReturnProductDetails = data.ReturnProductDetails.OrderBy(t => t.BillDate).ToList();
            data.SaleOtherDetails = data.SaleOtherDetails.OrderBy(t => t.BillDate).ToList();
            data.SaleProductDetails = data.SaleProductDetails.OrderBy(t => t.BillDate).ToList();

            data.BeginDate = model.BeginDate;
            data.EndDate = model.EndDate;
            data.CompanyId = model.CompanyId;
            data.CompanyName = company.data.CompanyName;
            data.BeginAmount = customerBeginAmount;
            data.EndAmount = customerEndAmount;
            data.TradeAmount = data.SaleProductDetails.Sum(t => t.Total);
            data.TradePayAmount = data.FinanceDetails.Sum(t => t.Total);
            data.TradeOutAmount = data.ReturnProductDetails.Sum(t => t.Total);

            return data;
        }
        /// <summary>
        /// 客户按批次对账
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ReconciliationBillModel> GetCustomerReconciliationBill(UserToken userToken, ReconciliationQueryModel model)
        {
            var data = new ReconciliationBillModel();
            data.BillDetails = new List<ReconciliationBillDetailModel>();

            var companyAPI = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            var company = await companyAPI.GetById(model.CompanyId, userToken.Token);
            var customerBeginAmount = await companyAPI.CustomerBeginAmount(model.CompanyId, model.BeginDate, userToken.Token);
            var customerEndAmount = await companyAPI.CustomerBeginAmount(model.CompanyId, model.EndDate, userToken.Token);

            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "5,7,20", CompanyId = model.CompanyId, CompanyType = 1, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = 1, PageSize = 999999999, }, userToken.Token);
            foreach (var item in finance.DataList)
            {
                var remark = "";
                switch (item.PayType)
                {
                    case PayTypeEnum.SaleAdvPay:
                        remark = $"预付款";
                        break;
                    case PayTypeEnum.RechargeReward:
                        remark = $"充值奖励";
                        break;
                    case PayTypeEnum.SalAdvRefund:
                        remark = $"退预付款";
                        break;
                    default:
                        break;
                }
                data.BillDetails.Add(new ReconciliationBillDetailModel()
                {
                    AccountName = item.AccountName,
                    SaleManName = item.MemberName,
                    BillDate = item.TransactionDate,
                    BillNo = item.FlowNo,
                    DeptName = item.DeptName,
                    PayTotal = item.Amount,
                    Remark = remark + (remark.Length > 0 ? "," : "") + item.Remark,
                    Total = (item.PayType == PayTypeEnum.SalAdvRefund ? -item.Amount : item.Amount),
                });
            }

            var query = await _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Company, HR_Member, HR_Dept>((a, b, d, f, g) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((a, b, d, f, g) => a.TenantId == userToken.TenantId && b.Status >= 0 && (b.SourceBillType / 10 == 2 || b.SourceBillType == 0) /*&& d.CompanyType == 2 && d.SupplyType == 2*/ && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((a, b, d, f, g) => b.CompanyId == model.CompanyId)
                .Select((a, b, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = SqlFunc.ToDateShort(b.BillDate),
                    Price = a.Price * (1 + a.Tax / 100),
                    Qty = a.Qty,
                    Total = a.Price * a.Qty,
                    DescQty = a.DescQty,
                    DespachoQty = a.DespachoQty,
                    EntradaQty = a.EntradaQty,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    f.MemberName,
                }).MergeTable()
                .GroupBy(t => new { t.BillType, t.DeptName, t.BillDate, t.Price, t.Remark, t.BillNo, t.MemberName, })
                .Select(t => new
                {
                    BillType = t.BillType,
                    DeptName = t.DeptName,
                    BillDate = t.BillDate,
                    Price = t.Price,
                    Qty = SqlFunc.AggregateSum(t.Qty),
                    Total = SqlFunc.AggregateSum(t.Total),
                    DescQty = SqlFunc.AggregateSum(t.DescQty),
                    DespachoQty = SqlFunc.AggregateSum(t.DespachoQty),
                    EntradaQty = SqlFunc.AggregateSum(t.EntradaQty),
                    Remark = t.Remark,
                    BillNo = t.BillNo,
                    MemberName = t.MemberName,
                }).ToListAsync();

            foreach (var item in query)
            {
                data.BillDetails.Add(new ReconciliationBillDetailModel()
                {
                    DeptName = item.DeptName,
                    BillDate = item.BillDate,
                    BillNo = item.BillNo,
                    TotalQty = Convert.ToInt32(item.DespachoQty),
                    TotalPrice = item.Price * item.DespachoQty,
                    ReturnQty = Convert.ToInt32(item.EntradaQty),
                    ReturnPrice = item.Price * item.EntradaQty,
                    Remark = item.Remark,
                    Total = (item.Price * item.DespachoQty) - (item.Price * item.EntradaQty),
                    SaleManName = item.MemberName,
                });
            }

            var sale = await _client.Queryable<SALE_Order, Sale_OrderOtherReceivable, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.OrderId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status > 0 && (b.SmearMoney > 0 || c.Amount > 0) && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
                //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
                .Select((b, c, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = b.BillDate,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    MemberName = f.MemberName,
                    c.Amount,
                    c.TransactionName,
                    b.SmearMoney,
                }).ToListAsync();
            var saleCost = await _client.Queryable<SALE_Order, Sale_OrderAssociatedCost, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.OrderId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status > 0 && c.IsBear == true && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
                //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
                .Select((b, c, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = b.BillDate,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    MemberName = f.MemberName,
                    c.Amount,
                    TransactionName = c.BigKindName,
                    b.SmearMoney,
                }).ToListAsync();
            sale.AddRange(saleCost);
            //var saleCost = await _client.Queryable<SALE_Order, Sale_OrderAssociatedCost, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.OrderId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
            //    //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
            //    .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status > 0 && c.IsBear == true && c.BigKind == Guid.Empty && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
            //    .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
            //    //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
            //    .Select((b, c, d, f, g) => new
            //    {
            //        BillType = b.BillType,
            //        DeptName = g.DeptName,
            //        BillDate = b.BillDate,
            //        Remark = b.Remark,
            //        BillNo = b.BillNo,
            //        MemberName = f.MemberName,
            //        c.Amount,
            //        c.BigKindName,
            //        b.SmearMoney,
            //    }).ToListAsync();

            foreach (var item in sale)
            {
                if (data.BillDetails.Where(t => t.BillNo == item.BillNo).Any() && item.Amount > 0)
                {
                    var temp = data.BillDetails.Where(t => t.BillNo == item.BillNo).First();
                    temp.OtherPrice += item.Amount;
                    temp.Total += item.Amount;
                    temp.OtherPriceRemark += $"{item.TransactionName}:{item.Amount}。";
                }
                else if (item.Amount > 0 || item.SmearMoney > 0)
                {
                    data.BillDetails.Add(new ReconciliationBillDetailModel()
                    {
                        DeptName = item.DeptName,
                        BillDate = item.BillDate,
                        BillNo = item.BillNo,
                        Remark = item.Remark,
                        SmearMoney = item.SmearMoney,
                        SaleManName = item.MemberName,
                        Total = -item.SmearMoney + item.Amount,
                        OtherPrice = item.Amount,
                        OtherPriceRemark = (item.SmearMoney > 0 ? $"抹零:{item.SmearMoney.ToString("F2")}" : "") + (item.Amount > 0 ? $"{item.TransactionName}:{item.Amount.ToString("F2")}。" : ""),
                    });
                }
            }
            data.BillDetails = data.BillDetails.OrderBy(t => t.BillDate).ToList();

            data.BeginDate = model.BeginDate;
            data.EndDate = model.EndDate;
            data.CompanyId = model.CompanyId;
            data.CompanyName = company.data.CompanyName;
            data.BeginAmount = customerBeginAmount;
            data.EndAmount = customerEndAmount;
            data.TradeAmount = data.BillDetails.Sum(t => t.TotalPrice);
            data.TradePayAmount = data.BillDetails.Sum(t => t.PayTotal);
            data.TradeOutAmount = data.BillDetails.Sum(t => t.ReturnPrice);

            return data;
        }
        /// <summary>
        /// 供应商按明细对账
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ReconciliationDetailModel> GetSupplierReconciliationDetail(UserToken userToken, ReconciliationQueryModel model)
        {
            var companyAPI = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            var company = await companyAPI.GetById(model.CompanyId, userToken.Token);
            var customerBeginAmount = await companyAPI.SupplierBeginAmount(model.CompanyId, model.BeginDate, userToken.Token);
            var customerEndAmount = await companyAPI.SupplierBeginAmount(model.CompanyId, model.EndDate, userToken.Token);

            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "9,11", CompanyId = model.CompanyId, CompanyType = 2, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = 1, PageSize = 999999999, }, userToken.Token);
            var data = new ReconciliationDetailModel();
            data.FinanceDetails = new List<ReconciliationFinanceDetailModel>();
            data.SaleProductDetails = new List<ReconciliationProductDetailModel>();
            data.ReturnProductDetails = new List<ReconciliationProductDetailModel>();
            data.SaleOtherDetails = new List<ReconciliationDetailOtherModel>();

            foreach (var d in finance.DataList)
            {
                var remark = "";
                var Total = 0m;
                switch (d.PayType)
                {
                    case PayTypeEnum.PurchaseAdvPay:
                        remark = $"采购定金";
                        Total = d.Amount;
                        break;
                    case PayTypeEnum.PurchaseAdvRefund:
                        remark = $"退采购定金";
                        Total = d.Amount;
                        break;
                    default:
                        break;
                }
                data.FinanceDetails.Add(new ReconciliationFinanceDetailModel()
                {
                    DeptName = "",
                    AccountName = d.AccountName,
                    BillDate = d.TransactionDate,
                    BillNo = d.RelatedBillNo,
                    Remark = remark + (remark.Length > 0 ? "," : "") + d.Remark,
                    Total = Total,
                });
            }

            var query = await _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Material, BAS_Company, BAS_SizeDetail, HR_Member, HR_Dept>((a, b, c, d, e, f, g) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, a.MaterialId == c.MaterialId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, a.SizeName == e.SizeName && a.TenantId == e.TenantId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((a, b, c, d, e, f, g) => a.TenantId == userToken.TenantId && b.Status >= 0 && (b.SourceBillType / 10 == 1 || b.SourceBillType == 0) /*&& d.CompanyType == 2 && d.SupplyType == 2*/ && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((a, b, c, d, e, f, g) => b.CompanyId == model.CompanyId)
                .Select((a, b, c, d, e, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    MaterialId = a.MaterialId,
                    PhotoUrl = c.PhotoUrl,
                    BillDate = SqlFunc.ToDateShort(b.BillDate),
                    MaterialNo = a.MaterialNo,
                    ColorName = a.ColorName,
                    SizeName = a.SizeName,
                    MaterialName = c.MaterialName,
                    Price = a.Price * (1 + a.Tax / 100),
                    Qty = a.Qty,
                    Total = a.Price * a.Qty,
                    Specs = a.Specs,
                    Remark = a.Remark,
                    BillNo = b.BillNo,
                }).MergeTable()
                .GroupBy(t => new { t.BillType, t.DeptName, t.MaterialId, t.PhotoUrl, t.BillDate, t.MaterialNo, t.ColorName, t.SizeName, t.MaterialName, t.Price, t.Specs, t.Remark, t.BillNo, })
                .Select(t => new
                {
                    BillType = t.BillType,
                    DeptName = t.DeptName,
                    MaterialId = t.MaterialId,
                    PhotoUrl = t.PhotoUrl,
                    BillDate = t.BillDate,
                    MaterialNo = t.MaterialNo,
                    ColorName = t.ColorName,
                    SizeName = t.SizeName,
                    MaterialName = t.MaterialName,
                    Price = t.Price,
                    Qty = SqlFunc.AggregateSum(t.Qty),
                    Total = SqlFunc.AggregateSum(t.Total),
                    Specs = t.Specs,
                    Remark = t.Remark,
                    BillNo = t.BillNo,
                }).ToListAsync();
            var saleData = query.Where(t => t.BillType == 41).ToList();
            var returnData = query.Where(t => t.BillType == 40).ToList();
            foreach (var item in saleData)
            {
                data.SaleProductDetails.Add(new ReconciliationProductDetailModel() { DeptName = item.DeptName, SizeName = item.SizeName, Specs = item.Specs, BillDate = item.BillDate, BillNo = item.BillNo, ColorName = item.ColorName, MaterialId = item.MaterialId, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, PhotoUrl = item.PhotoUrl, Price = item.Price, Qty = item.Qty, Remark = item.Remark, Total = item.Total, });
            }
            foreach (var item in returnData)
            {
                data.ReturnProductDetails.Add(new ReconciliationProductDetailModel() { DeptName = item.DeptName, SizeName = item.SizeName, Specs = item.Specs, BillDate = item.BillDate, BillNo = item.BillNo, ColorName = item.ColorName, MaterialId = item.MaterialId, MaterialName = item.MaterialName, MaterialNo = item.MaterialNo, PhotoUrl = item.PhotoUrl, Price = item.Price, Qty = -item.Qty, Remark = item.Remark, Total = -item.Total, });
            }

            var sale = await _client.Queryable<MS_Purchase, MS_PurchaseOtherReceivable, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.PurchaseId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status >= 0 && (b.SmearMoney > 0 || c.Amount > 0) && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
                //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
                .Select((b, c, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = b.BillDate,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    MemberName = f.MemberName,
                    c.Amount,
                    c.TransactionName,
                    b.SmearMoney,
                }).ToListAsync();

            foreach (var item in sale)
            {
                if (data.SaleOtherDetails.Where(t => t.BillNo == item.BillNo).Any() && item.Amount > 0)
                {
                    var temp = data.SaleOtherDetails.Where(t => t.BillNo == item.BillNo).First();
                    temp.OtherPrice += item.Amount;
                    temp.Total += item.Amount;
                    temp.OtherPriceRemark += $"{item.TransactionName}:{item.Amount}。";
                }
                else if (item.Amount > 0 || item.SmearMoney > 0)
                {
                    data.SaleOtherDetails.Add(new ReconciliationDetailOtherModel()
                    {
                        DeptName = item.DeptName,
                        BillDate = item.BillDate,
                        BillNo = item.BillNo,
                        Remark = item.Remark,
                        SmearMoney = item.SmearMoney,
                        SaleManName = item.MemberName,
                        Total = -item.SmearMoney + item.Amount,
                        OtherPrice = item.Amount,
                        //OtherPriceRemark = item.Amount > 0 ? $"{item.TransactionName}:{item.Amount}。" : "",
                        OtherPriceRemark = (item.SmearMoney > 0 ? $"抹零:{item.SmearMoney.ToString("F2")}" : "") + (item.Amount > 0 ? $"{item.TransactionName}:{item.Amount.ToString("F2")}。" : ""),
                    });
                }
            }
            data.FinanceDetails = data.FinanceDetails.OrderBy(t => t.BillDate).ToList();
            data.ReturnProductDetails = data.ReturnProductDetails.OrderBy(t => t.BillDate).ToList();
            data.SaleOtherDetails = data.SaleOtherDetails.OrderBy(t => t.BillDate).ToList();
            data.SaleProductDetails = data.SaleProductDetails.OrderBy(t => t.BillDate).ToList();

            data.BeginDate = model.BeginDate;
            data.EndDate = model.EndDate;
            data.CompanyId = model.CompanyId;
            data.CompanyName = company.data.CompanyName;
            data.BeginAmount = customerBeginAmount;
            data.EndAmount = customerEndAmount;
            data.TradeAmount = data.SaleProductDetails.Sum(t => t.Total);
            data.TradePayAmount = data.FinanceDetails.Sum(t => t.Total);
            data.TradeOutAmount = data.ReturnProductDetails.Sum(t => t.Total);

            return data;
        }
        /// <summary>
        /// 供应商按批次对账
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ReconciliationBillModel> GetSupplierReconciliationBill(UserToken userToken, ReconciliationQueryModel model)
        {
            var data = new ReconciliationBillModel();
            data.BillDetails = new List<ReconciliationBillDetailModel>();

            var companyAPI = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            var company = await companyAPI.GetById(model.CompanyId, userToken.Token);
            var customerBeginAmount = await companyAPI.SupplierBeginAmount(model.CompanyId, model.BeginDate, userToken.Token);
            var customerEndAmount = await companyAPI.SupplierBeginAmount(model.CompanyId, model.EndDate, userToken.Token);

            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "9,11", CompanyId = model.CompanyId, CompanyType = 2, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = 1, PageSize = 999999999, }, userToken.Token);
            foreach (var item in finance.DataList)
            {
                var remark = "";
                switch (item.PayType)
                {
                    case PayTypeEnum.PurchaseAdvPay:
                        remark = $"采购定金";
                        break;
                    case PayTypeEnum.PurchaseAdvRefund:
                        remark = $"退采购定金";
                        break;
                    default:
                        break;
                }
                data.BillDetails.Add(new ReconciliationBillDetailModel()
                {
                    AccountName = item.AccountName,
                    SaleManName = item.MemberName,
                    BillDate = item.TransactionDate,
                    BillNo = item.FlowNo,
                    DeptName = item.DeptName,
                    PayTotal = item.Amount,
                    Remark = remark + (remark.Length > 0 ? "," : "") + item.Remark,
                    Total = (item.PayType == PayTypeEnum.SalAdvRefund ? -item.Amount : item.Amount),
                });
            }

            var query = await _client.Queryable<MS_StrogeDetail, MS_Stroge, BAS_Company, HR_Member, HR_Dept>((a, b, d, f, g) => new object[] { JoinType.Left, a.StrogeId == b.Id, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((a, b, d, f, g) => a.TenantId == userToken.TenantId && b.Status >= 0 && (b.SourceBillType / 10 == 1 || b.SourceBillType == 0) /*&& d.CompanyType == 2 && d.SupplyType == 2*/ && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((a, b, d, f, g) => b.CompanyId == model.CompanyId)
                .Select((a, b, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = SqlFunc.ToDateShort(b.BillDate),
                    Price = a.Price * (1 + a.Tax / 100),
                    Qty = a.Qty,
                    Total = a.Price * a.Qty,
                    DescQty = a.DescQty,
                    DespachoQty = a.DespachoQty,
                    EntradaQty = a.EntradaQty,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    f.MemberName,
                }).MergeTable()
                .GroupBy(t => new { t.BillType, t.DeptName, t.BillDate, t.Price, t.Remark, t.BillNo, t.MemberName, })
                .Select(t => new
                {
                    BillType = t.BillType,
                    DeptName = t.DeptName,
                    BillDate = t.BillDate,
                    Price = t.Price,
                    Qty = SqlFunc.AggregateSum(t.Qty),
                    Total = SqlFunc.AggregateSum(t.Total),
                    DescQty = SqlFunc.AggregateSum(t.DescQty),
                    DespachoQty = SqlFunc.AggregateSum(t.DespachoQty),
                    EntradaQty = SqlFunc.AggregateSum(t.EntradaQty),
                    Remark = t.Remark,
                    BillNo = t.BillNo,
                    MemberName = t.MemberName,
                }).ToListAsync();

            foreach (var item in query)
            {
                data.BillDetails.Add(new ReconciliationBillDetailModel()
                {
                    DeptName = item.DeptName,
                    BillDate = item.BillDate,
                    BillNo = item.BillNo,
                    ReturnQty = Convert.ToInt32(item.DespachoQty),
                    ReturnPrice = item.Price * item.DespachoQty,
                    TotalQty = Convert.ToInt32(item.EntradaQty),
                    TotalPrice = item.Price * item.EntradaQty,
                    Remark = item.Remark,
                    Total = (item.Price * item.DespachoQty) - (item.Price * item.EntradaQty),
                    SaleManName = item.MemberName,
                });
            }

            var sale = await _client.Queryable<MS_Purchase, MS_PurchaseOtherReceivable, BAS_Company, HR_Member, HR_Dept>((b, c, d, f, g) => new object[] { JoinType.Left, c.PurchaseId == b.KeyId, JoinType.Left, b.CompanyId == d.CompanyId, JoinType.Left, d.MemberId == f.Id, JoinType.Left, f.DeptId == g.DeptID, })
                //.GroupBy((a, b, c, d, e) => new { b.BillDate, d.CompanyName, a.MaterialNo, c.CompanyMaterialNo, a.ColorName, a.SizeName, c.MaterialName, a.Price, b.BillType, a.Qty, a.Specs, a.Remark, e.OrderId, })
                .Where((b, c, d, f, g) => b.TenantId == userToken.TenantId && b.Status >= 0 && (b.SmearMoney > 0 || c.Amount > 0) && SqlFunc.Between(b.CreateTime, model.BeginDate, model.EndDate))
                .Where((b, c, d, f, g) => b.CompanyId == model.CompanyId)
                //.GroupBy((b, c, d, f, g) => new { b.BillType, c.Amount, c.TransactionName, g.DeptName, b.BillDate, b.Remark, b.BillNo, f.MemberName, b.SmearMoney, c.Amount, c.TransactionName, })
                .Select((b, c, d, f, g) => new
                {
                    BillType = b.BillType,
                    DeptName = g.DeptName,
                    BillDate = b.BillDate,
                    Remark = b.Remark,
                    BillNo = b.BillNo,
                    MemberName = f.MemberName,
                    c.Amount,
                    c.TransactionName,
                    b.SmearMoney,
                }).ToListAsync();

            foreach (var item in sale)
            {
                if (data.BillDetails.Where(t => t.BillNo == item.BillNo).Any() && item.Amount > 0)
                {
                    var temp = data.BillDetails.Where(t => t.BillNo == item.BillNo).First();
                    temp.OtherPrice += item.Amount;
                    temp.Total += item.Amount;
                    temp.OtherPriceRemark += $"{item.TransactionName}:{item.Amount}。";
                }
                else if (item.Amount > 0 || item.SmearMoney > 0)
                {
                    data.BillDetails.Add(new ReconciliationBillDetailModel()
                    {
                        DeptName = item.DeptName,
                        BillDate = item.BillDate,
                        BillNo = item.BillNo,
                        Remark = item.Remark,
                        SmearMoney = item.SmearMoney,
                        SaleManName = item.MemberName,
                        Total = -item.SmearMoney + item.Amount,
                        OtherPrice = item.Amount,
                        OtherPriceRemark = (item.SmearMoney > 0 ? $"抹零:{item.SmearMoney.ToString("F2")}" : "") + (item.Amount > 0 ? $"{item.TransactionName}:{item.Amount.ToString("F2")}。" : ""),
                    });
                }
            }
            data.BillDetails = data.BillDetails.OrderBy(t => t.BillDate).ToList();

            data.BeginDate = model.BeginDate;
            data.EndDate = model.EndDate;
            data.CompanyId = model.CompanyId;
            data.CompanyName = company.data.CompanyName;
            data.BeginAmount = customerBeginAmount;
            data.EndAmount = customerEndAmount;
            data.TradeAmount = data.BillDetails.Sum(t => t.TotalPrice);
            data.TradePayAmount = data.BillDetails.Sum(t => t.PayTotal);
            data.TradeOutAmount = data.BillDetails.Sum(t => t.ReturnPrice);

            return data;
        }

        public async Task<List<ReconciliationSummaryModel>> GetCustomerReconciliationSummary(UserToken userToken, ReconciliationQueryModel model)
        {
            var companyApi = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            var companyIds = new List<Guid>();
            if (model.CompanyId != Guid.Empty)
                companyIds.Add(model.CompanyId);
            var beginTotals = await companyApi.GetCustomerAmountSummary(new Data.ViewModel.BAS.Company.CompanyAmountSummaryReqModel() { CompanyIds = companyIds, EndDate = model.BeginDate }, userToken.Token);
            var endTotals = await companyApi.GetCustomerAmountSummary(new Data.ViewModel.BAS.Company.CompanyAmountSummaryReqModel() { CompanyIds = companyIds, EndDate = model.EndDate }, userToken.Token);
            var companyList = await _client.Queryable<BAS_Company>()
                .Where(a => a.TenantId == userToken.TenantId && a.CompanyType == 1 && a.IsDelete == false)
                .WhereIF(model.CompanyId != Guid.Empty, a => a.CompanyId == model.CompanyId).ToListAsync();
            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "5,7", CompanyType = 1, CompanyId = model.CompanyId, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = 1, PageSize = 999999999, }, userToken.Token);

            var result = new List<ReconciliationSummaryModel>();
            foreach (var item in companyList)
            {
                var temp = new ReconciliationSummaryModel();
                temp.CompanyId = item.CompanyId;
                temp.CompanyName = item.CompanyName;

                var OtherPrice = 0m;
                var SmearMoney = 0m;
                var TotalPrice = 0m;
                var DespachoQty = 0m;
                var EntradaQty = 0m;
                var RewardAmount = 0m;
                var TradePayAmount = 0m;
                if (beginTotals.Where(t => t.CompanyId == item.CompanyId).Any())
                {
                    var total = beginTotals.Where(t => t.CompanyId == item.CompanyId);
                    temp.BeginAmount = total.Sum(t => t.CapitalflowAmount) + total.Sum(t => t.SmearMoney) + total.Sum(t => t.RewardAmount) - total.Sum(t => t.ReturnAmount) - total.Sum(t => t.StrogeAmount) - total.Sum(t => t.OrderOtherAmount);
                    OtherPrice = total.Sum(t => t.OrderOtherAmount);
                    SmearMoney = total.Sum(t => t.SmearMoney);
                    TotalPrice = total.Sum(t => t.StrogeAmount);
                    DespachoQty = total.Sum(t => t.DespachoQty);
                    EntradaQty = total.Sum(t => t.EntradaQty);
                    RewardAmount = total.Sum(t => t.RewardAmount);
                    TradePayAmount = finance.DataList.Where(t => t.CompanyId == item.CompanyId).Sum(t => t.Amount);
                }
                if (endTotals.Where(t => t.CompanyId == item.CompanyId).Any())
                {
                    var total = endTotals.Where(t => t.CompanyId == item.CompanyId);
                    temp.EndAmount = total.Sum(t => t.CapitalflowAmount) + total.Sum(t => t.SmearMoney) + total.Sum(t => t.RewardAmount) - total.Sum(t => t.ReturnAmount) - total.Sum(t => t.StrogeAmount) - total.Sum(t => t.OrderOtherAmount); ;
                    temp.OtherPrice = total.Sum(t => t.OrderOtherAmount) - OtherPrice;
                    temp.SmearMoney = total.Sum(t => t.SmearMoney) - SmearMoney;
                    temp.TotalPrice = total.Sum(t => t.StrogeAmount) - TotalPrice;
                    temp.DespachoQty = total.Sum(t => t.DespachoQty) - DespachoQty;
                    temp.EntradaQty = total.Sum(t => t.EntradaQty) - EntradaQty;
                    temp.RewardAmount = total.Sum(t => t.RewardAmount) - RewardAmount;
                    temp.TradePayAmount = finance.DataList.Where(t => t.CompanyId == item.CompanyId).Sum(t => t.Amount) - TradePayAmount;

                    temp.DeliverFee = 0;
                }

                result.Add(temp);
            }
            return result;
        }
        public async Task<List<ReconciliationSummaryModel>> GetSupplierReconciliationSummary(UserToken userToken, ReconciliationQueryModel model)
        {
            var companyApi = RefitExtensions.For<ICompanyAPI>(Appsettings.BaseUrl);
            var companyIds = new List<Guid>();
            if (model.CompanyId != Guid.Empty)
                companyIds.Add(model.CompanyId);
            var beginTotals = await companyApi.GetSupplierAmountSummary(new Data.ViewModel.BAS.Company.CompanyAmountSummaryReqModel() { CompanyIds = companyIds, EndDate = model.BeginDate }, userToken.Token);
            var endTotals = await companyApi.GetSupplierAmountSummary(new Data.ViewModel.BAS.Company.CompanyAmountSummaryReqModel() { CompanyIds = companyIds, EndDate = model.EndDate }, userToken.Token);
            var companyList = await _client.Queryable<BAS_Company>()
                .Where(a => a.TenantId == userToken.TenantId && a.CompanyType == 2 && a.IsDelete == false)
                .WhereIF(model.CompanyId != Guid.Empty, a => a.CompanyId == model.CompanyId).ToListAsync();
            var financeApi = RefitExtensions.For<IFinanceApi>(Appsettings.BaseUrl);
            var finance = await financeApi.FlowsTotal(new CapitalflowSearchModel() { PayType = "9,11", CompanyType = 2, BeginTime = model.BeginDate, EndTime = model.EndDate, PageIndex = 1, PageSize = 999999999, }, userToken.Token);

            var result = new List<ReconciliationSummaryModel>();
            foreach (var item in companyList)
            {
                var temp = new ReconciliationSummaryModel();
                temp.CompanyId = item.CompanyId;
                temp.CompanyName = item.CompanyName;

                var OtherPrice = 0m;
                var SmearMoney = 0m;
                var TotalPrice = 0m;
                var DespachoQty = 0m;
                var EntradaQty = 0m;
                var RewardAmount = 0m;
                var TradePayAmount = 0m;
                if (beginTotals.Where(t => t.CompanyId == item.CompanyId).Any())
                {
                    var total = beginTotals.Where(t => t.CompanyId == item.CompanyId);
                    temp.BeginAmount = total.Sum(t => t.CapitalflowAmount) + total.Sum(t => t.SmearMoney) + total.Sum(t => t.RewardAmount) - total.Sum(t => t.ReturnAmount) - total.Sum(t => t.StrogeAmount) - total.Sum(t => t.OrderOtherAmount);
                    OtherPrice = total.Sum(t => t.OrderOtherAmount);
                    SmearMoney = total.Sum(t => t.SmearMoney);
                    TotalPrice = total.Sum(t => t.StrogeAmount);
                    DespachoQty = total.Sum(t => t.DespachoQty);
                    EntradaQty = total.Sum(t => t.EntradaQty);
                    RewardAmount = total.Sum(t => t.RewardAmount);
                    TradePayAmount = finance.DataList.Where(t => t.CompanyId == item.CompanyId).Sum(t => t.Amount);
                }
                if (endTotals.Where(t => t.CompanyId == item.CompanyId).Any())
                {
                    var total = endTotals.Where(t => t.CompanyId == item.CompanyId);
                    temp.EndAmount = total.Sum(t => t.CapitalflowAmount) + total.Sum(t => t.SmearMoney) + total.Sum(t => t.RewardAmount) - total.Sum(t => t.ReturnAmount) - total.Sum(t => t.StrogeAmount) - total.Sum(t => t.OrderOtherAmount); ;
                    temp.OtherPrice = total.Sum(t => t.OrderOtherAmount) - OtherPrice;
                    temp.SmearMoney = total.Sum(t => t.SmearMoney) - SmearMoney;
                    temp.TotalPrice = -(total.Sum(t => t.StrogeAmount) - TotalPrice);
                    temp.DespachoQty = total.Sum(t => t.DespachoQty) - DespachoQty;
                    temp.EntradaQty = total.Sum(t => t.EntradaQty) - EntradaQty;
                    temp.RewardAmount = total.Sum(t => t.RewardAmount) - RewardAmount;
                    temp.TradePayAmount = finance.DataList.Where(t => t.CompanyId == item.CompanyId).Sum(t => t.Amount) - TradePayAmount;

                    temp.DeliverFee = 0;
                }

                result.Add(temp);
            }
            return result;
        }
    }
}
